Submission #1087881

#TimeUsernameProblemLanguageResultExecution timeMemory
1087881alexander707070Duathlon (APIO18_duathlon)C++14
71 / 100
691 ms27616 KiB
#include<bits/stdc++.h> #define MAXN 200007 using namespace std; long long n,m,a[MAXN],b[MAXN],k; vector< pair<int,int> > v[MAXN]; vector<int> tree[MAXN]; long long sz[MAXN],sum[MAXN],szcomp[MAXN],ans; bool li[MAXN],bridge[MAXN]; int dp[MAXN],low[MAXN]; long long comp[MAXN],where[MAXN]; void bcc(int x,int p,int dep,int edge){ li[x]=true; dp[x]=low[x]=dep; for(int i=0;i<v[x].size();i++){ if(!li[v[x][i].first]){ bcc(v[x][i].first,x,dep+1,v[x][i].second); low[x]=min(low[x],low[v[x][i].first]); }else if(v[x][i].first!=p){ low[x]=min(low[x],dp[v[x][i].first]); } } if(p!=0 and low[x]==dp[x]){ bridge[edge]=true; } } void mark(int x){ comp[k]++; where[x]=k; li[x]=true; for(int i=0;i<v[x].size();i++){ if(li[v[x][i].first] or bridge[v[x][i].second])continue; mark(v[x][i].first); } } void dfs(int x,int p){ sz[x]=comp[x]; for(int i=0;i<tree[x].size();i++){ if(tree[x][i]==p or sz[tree[x][i]]!=0)continue; dfs(tree[x][i],x); sum[x]+=sz[tree[x][i]]*(sz[tree[x][i]]-1); sz[x]+=sz[tree[x][i]]; } } void dfs2(int x,int p,int s){ szcomp[x]=s; for(int i=0;i<tree[x].size();i++){ if(tree[x][i]==p or szcomp[tree[x][i]]!=0)continue; dfs2(tree[x][i],x,s); } sum[x]+=(s-sz[x])*(s-sz[x]-1); } deque<int> q; bool vis[MAXN]; int par[MAXN]; void dobfs(int x){ for(int i=1;i<=n;i++)li[i]=false; for(int i=1;i<=n;i++){ random_shuffle(v[i].begin(),v[i].end()); } q.push_back(x); par[x]=0; li[x]=true; while(!q.empty()){ int curr; if(rand()%10<7){ curr=q.front(); q.pop_front(); }else{ curr=q.back(); q.pop_back(); } for(int i=0;i<v[curr].size();i++){ if(li[v[curr][i].first] or vis[v[curr][i].first])continue; q.push_back(v[curr][i].first); li[v[curr][i].first]=true; par[v[curr][i].first]=curr; } } } bool check(int x,int y,int z){ for(int i=1;i<=n;i++)vis[i]=false; dobfs(x); if(!li[y])return false; int w=y; while(y!=x){ y=par[y]; vis[y]=true; } if(vis[z])return false; dobfs(z); return li[w]; } void brute(){ int res=0; for(int i=1;i<=n;i++){ for(int f=1;f<=n;f++){ for(int t=1;t<=n;t++){ if(i==f or f==t or i==t or i>t)continue; for(int test=1;test<=3;test++){ if(check(i,f,t) or check(t,f,i)){ res+=2; break; } } } } } cout<<res<<"\n"; return; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1;i<=m;i++){ cin>>a[i]>>b[i]; v[a[i]].push_back({b[i],i}); v[b[i]].push_back({a[i],i}); } if(n<=50){ brute(); return 0; } for(int i=1;i<=n;i++){ if(!li[i])bcc(i,0,0,0); } for(int i=1;i<=n;i++)li[i]=false; for(int i=1;i<=n;i++){ if(!li[i]){ k++; mark(i); } } for(int i=1;i<=m;i++){ if(where[a[i]]==where[b[i]])continue; tree[where[a[i]]].push_back(where[b[i]]); tree[where[b[i]]].push_back(where[a[i]]); } for(int i=1;i<=k;i++){ if(sz[i]==0){ dfs(i,0); dfs2(i,0,sz[i]); } } for(int i=1;i<=k;i++){ ans+=(long long) comp[i]*((szcomp[i]-1)*(szcomp[i]-2)-sum[i]); ans-=(long long) 2*(comp[i]-1)*(szcomp[i]-comp[i]); } for(int i=1;i<=n;i++){ long long res=0,sq=0; for(int f=0;f<v[i].size();f++){ if(where[i]==where[v[i][f].first])continue; if(sz[where[i]]>sz[where[v[i][f].first]]){ res+=sz[where[v[i][f].first]]; sq+=(sz[where[v[i][f].first]]-1)*sz[where[v[i][f].first]]; }else{ res+=(szcomp[where[i]]-sz[where[i]]); sq+=(szcomp[where[i]]-sz[where[i]])*(szcomp[where[i]]-sz[where[i]]-1); } } res=res*(res-1); res-=sq; ans-=(long long) (comp[where[i]]-1)*res; } cout<<ans<<"\n"; return 0; } /** 19 24 1 2 2 3 3 4 4 1 5 6 6 7 7 5 8 9 9 10 10 8 11 12 12 13 13 11 14 15 15 16 16 14 17 18 18 19 17 19 7 8 4 5 7 11 13 17 12 14 */

Compilation message (stderr)

count_triplets.cpp: In function 'void bcc(int, int, int, int)':
count_triplets.cpp:20:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   20 |     for(int i=0;i<v[x].size();i++){
      |                 ~^~~~~~~~~~~~
count_triplets.cpp: In function 'void mark(int)':
count_triplets.cpp:39:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   39 |     for(int i=0;i<v[x].size();i++){
      |                 ~^~~~~~~~~~~~
count_triplets.cpp: In function 'void dfs(int, int)':
count_triplets.cpp:48:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   48 |     for(int i=0;i<tree[x].size();i++){
      |                 ~^~~~~~~~~~~~~~~
count_triplets.cpp: In function 'void dfs2(int, int, int)':
count_triplets.cpp:60:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   60 |     for(int i=0;i<tree[x].size();i++){
      |                 ~^~~~~~~~~~~~~~~
count_triplets.cpp: In function 'void dobfs(int)':
count_triplets.cpp:90:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   90 |         for(int i=0;i<v[curr].size();i++){
      |                     ~^~~~~~~~~~~~~~~
count_triplets.cpp: In function 'int main()':
count_triplets.cpp:193:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  193 |         for(int f=0;f<v[i].size();f++){
      |                     ~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...