Submission #684188

#TimeUsernameProblemLanguageResultExecution timeMemory
684188starplatIslands (IOI08_islands)C++14
70 / 100
1062 ms131072 KiB
#include <bits/stdc++.h> #define int long long using namespace std; int n,u,w,vis[1000005],no[1000005],is[1000005]; int pt,done,cycle[1000005],bck[1000005],mx,ans; int node,dist,dp[1000005],par[2000005],we[2000005]; vector<pair<int,int>> g[1000005]; void dfs(int x,int p){ if (done) return; if (vis[x]){ int cnt=0; for (auto i:g[x]) cnt+=i.first==p; if (cnt==2){ cycle[++pt]=x; cycle[++pt]=p; is[x]=true; is[p]=true; } else { while (p!=x){ is[p]=true; cycle[++pt]=p; p=bck[p]; if (p==-1) break; } is[x]=true; cycle[++pt]=x; } done=true; } else { vis[x]=1; bck[x]=p; for (auto i:g[x]){ if (i.first!=p) dfs(i.first,x); } } } void mem(int x){ no[x]=1; for (auto i:g[x]){ if (!no[i.first]) mem(i.first); } } void dfs1(int x,int p,int d){ if (d>dist) { node=x; dist=d; } for (auto i:g[x]) { if (i.first!=p && !is[i.first]) dfs1(i.first,x,d+i.second); } } void treedp(int x,int p){ for (auto i:g[x]){ if (is[i.first] || i.first==p) continue; treedp(i.first,x); } for (auto i:g[x]){ if (is[i.first] || i.first==p) continue; dp[x]=max(dp[x],dp[i.first]+i.second); } if (p==-1){ vector <int> q; for (auto i:g[x]){ if (is[i.first] || i.first==p) continue; q.push_back(dp[i.first]+i.second); } sort(q.begin(),q.end(),greater<int>()); if (q.size()>1){ mx=max(mx,q[0]+q[1]); } if (q.size()) mx=max(q[0],mx); } } int weight(int x,int tar){ for (auto i:g[x]) if (i.first==tar) return i.second; return 0; } void work(){ int sum=0; priority_queue<pair<int,int>> q; for (int i=2;i<=pt;i++) we[i]=we[i+pt]=weight(cycle[i-1],cycle[i]); we[pt+1]=weight(cycle[pt],cycle[1]); for (int i=1;i<=2*pt;i++) par[i]=par[i-1]+we[i]; for (int i=2;i<=pt;i++) q.push({par[i]+dp[cycle[i]],i}); for (int i=1;i<=pt;i++){ while (!q.empty() && q.top().second<=i) q.pop(); if (!q.empty()) mx=max(mx,q.top().first+dp[cycle[i]]-sum); // cout<<i<<" "<<q.top().first+dp[cycle[i]]-sum<<"\n"; sum+=we[i+1]; q.push({par[pt+i]-par[i+1]+dp[cycle[i]]+sum,pt+i}); } } signed main(){ cin>>n; for (int i=1;i<=n;i++){ cin>>u>>w; g[i].push_back({u,w}); g[u].push_back({i,w}); bck[i]=-1; } for (int i=1;i<=n;i++){ if (no[i]) continue; node=mx=dist=done=pt=0; dfs(i,-1); mem(i); if (done){ for (int j=1;j<=pt;j++){ treedp(cycle[j],-1); for (auto k:g[cycle[j]]){ if (is[k.first]) continue; node=dist=0; dfs1(k.first,-1,0); dfs1(node,-1,0); mx=max(mx,dist); } } if (pt==2){ int tmp=0; for (auto j:g[cycle[1]]){ if (j.first==cycle[2]) tmp=max(tmp,j.second); } mx=max(mx,dp[cycle[1]]+dp[cycle[2]]+tmp); } else { work(); reverse(cycle+1,cycle+1+pt); work(); } } else { dfs1(i,-1,0); dfs1(node,-1,0); mx=max(mx,dist); } // cout<<mx<<"\n"; ans+=mx; } cout<<ans<<"\n"; }
#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...