Submission #53888

#TimeUsernameProblemLanguageResultExecution timeMemory
53888DiuvenIslands (IOI08_islands)C++11
100 / 100
1779 ms206600 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, ll> pil; const int MX=1000010; const ll inf=2e17; int n, A[MX], C[MX]; vector<pil> G[MX]; bool done[MX]; ll D[MX]; bool vis[MX]; // list all vertices void dfs1(int v, vector<int> &V){ done[v]=true; V.push_back(v); for(pil &e:G[v]){ int x=e.first; if(done[x]) continue; dfs1(x,V); } } // find cycle int found=-1; int dep[MX], now; void dfs2(int v, int p, vector<int> &V){ dep[v]=++now; for(pil &e:G[v]){ int x; ll c; tie(x,c)=e; if(p==x) continue; if(dep[x]>=0) found=x; else dfs2(x,v,V); if(found>=0){ if(dep[v]>=dep[found]) V.push_back(v); return; } } --now; } // farthest point ll dist[MX]; int dfs3(int v){ int res=v; for(pil &e:G[v]){ int x; ll c; tie(x,c)=e; if(dist[x]>=0) continue; dist[x]=dist[v]+c; int y=dfs3(x); if(dist[y]>dist[res]) res=y; } return res; } ll solve_tree(vector<int> &V){ int s=V[0]; for(int v:V) dist[v]=-1; dist[s]=0; int u=dfs3(s); for(int v:V) dist[v]=-1; dist[u]=0; int v=dfs3(u); return dist[v]; } bool incyc[MX]; ll arm[MX], scd[MX]; // longest path from v in cyc void dfs4(int v){ arm[v]=0; for(pil &e:G[v]){ int x; ll c; tie(x,c)=e; if(incyc[x] || arm[x]>=0) continue; dfs4(x); ll now=arm[x]+c; scd[v]=max(scd[v], now); if(scd[v]>arm[v]) swap(scd[v], arm[v]); } } ll Val[2*MX], Len[2*MX], Sum[2*MX]; vector<int> V, cyc; ll solve(int s){ // cout<<"\nSOLVE ON "<<s<<'\n'; V.clear(), cyc.clear(); dfs1(s, V); found=-1, now=0; for(int v:V) dep[v]=-1; dfs2(s, -1, cyc); if(cyc.empty()) return solve_tree(V); ll res=0; for(int v:V) arm[v]=-1, scd[v]=0; for(int v:cyc) incyc[v]=true, arm[v]=0; for(int v:cyc) dfs4(v); for(int v:V) res=max(res, arm[v]+scd[v]); int sz=cyc.size(); Sum[0]=0; for(int i=0; i<sz; i++){ int v=cyc[i]; Val[i]=arm[v]; int nxt=cyc[(i+1)%sz]; for(pil &e:G[v]) if(e.first==nxt) Len[i]=e.second; Sum[i+1]=Sum[i]+Len[i]; } for(int i=sz; i<2*sz; i++) Sum[i]=Sum[i%sz]+Sum[sz]; deque<int> Q; for(int j=0; j<=2*sz-1; j++){ int i=j%sz; while(!Q.empty() && Q.front()<=j-sz) Q.pop_front(); if(!Q.empty()){ int x=Q.front(); ll now=Val[x%sz] + Val[i] + Sum[j]-Sum[x]; res=max(res, now); } while(!Q.empty()){ int x=Q.back(); ll a=Val[x%sz]-Sum[x]; ll b=Val[j%sz]-Sum[j]; if(a<=b) Q.pop_back(); else break; } Q.push_back(j); } return res; for(int i=0; i<sz; i++) for(int j=i+1; j<sz; j++){ ll dist=max(Sum[j]-Sum[i], Sum[sz]+Sum[i]-Sum[j]); ll now=dist+Val[i]+Val[j]; // printf("%d - %d : %lld (%lld)\n", cyc[i], cyc[j], now, dist); res=max(res, now); } return res; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n; for(int u=1; u<=n; u++){ int v, c; cin>>v>>c; A[u]=v, C[u]=c; if(v<u && A[v]==u){ C[u]=max(C[u], C[v]); C[v]=-1; } } for(int i=1; i<=n; i++){ if(C[i]<0) continue; G[i].push_back({A[i], C[i]}); G[A[i]].push_back({i, C[i]}); } ll ans=0; for(int i=1; i<=n; i++){ if(done[i]) continue; ans+=solve(i); } cout<<ans; return 0; }
#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...