1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <queue> #define MAXN 1000005 #define LL long long using namespace std;
int n, id, l=1, r, cnt, head[MAXN], belong[MAXN], deg[MAXN], q[MAXN*2]; LL ans, dia[MAXN], len[MAXN], f[MAXN*2], g[MAXN*2]; bool vis[MAXN];
struct Edge {int next, to, dis;} edge[MAXN*2];
void addedge(int x, int y, LL z) { edge[++cnt].next=head[x]; edge[cnt].to=y; edge[cnt].dis=z; head[x]=cnt; deg[y]++; }
void dfs(int x, int id) { belong[x]=id; for(int i=head[x]; i; i=edge[i].next) { int to=edge[i].to; if(!belong[to]) dfs(to, id); } }
void topsort() { for(int i=1; i<=n; i++) if(deg[i]==1) q[++r]=i; while(l<=r) { int x=q[l++]; for(int i=head[x]; i; i=edge[i].next) { int to=edge[i].to; if(deg[to]<=1) continue; deg[to]--; dia[belong[x]]=max(dia[belong[x]], len[to]+len[x]+edge[i].dis); len[to]=max(len[to], len[x]+edge[i].dis); if(deg[to]==1) q[++r]=to; } } }
void dp(int x) { int y=x, tot=0; while(1) { bool flag=false; deg[y]=1; f[++tot]=len[y]; for(int i=head[y]; i; i=edge[i].next) { int to=edge[i].to; if(deg[to]<=1) continue; g[tot+1]=g[tot]+edge[i].dis; flag=true; y=to; } if(!flag) break; } if(tot==2) { int temp=0; for(int i=head[y]; i; i=edge[i].next) if(edge[i].to==x) temp=max(temp, edge[i].dis); dia[belong[x]]=max(dia[belong[x]], len[x]+len[y]+temp); } for(int i=head[y]; i; i=edge[i].next) { int to=edge[i].to; if(to==x) g[tot+1]=g[tot]+edge[i].dis; } for(int i=1; i<=tot; i++) { f[i+tot]=f[i]; g[i+tot]=g[tot+1]+g[i]; } l=r=1; q[1]=1; for(int i=2; i<2*tot; i++) { while(l<=r && i-q[l]>=tot) l++; dia[belong[x]]=max(dia[belong[x]], f[i]+f[q[l]]+g[i]-g[q[l]]); while(l<=r && f[q[r]]+g[i]-g[q[r]]<=f[i]) r--; q[++r]=i; } }
int main() { scanf("%d", &n); for(int i=1; i<=n; i++) { int x, y; scanf("%d%d", &x, &y); addedge(i, x, y); addedge(x, i, y); } for(int i=1; i<=n; i++) if(!belong[i]) dfs(i, ++id); topsort(); for(int i=1; i<=n; i++) { if(deg[i]<=1 || vis[belong[i]]) continue; vis[belong[i]]=true; dp(i); ans+=dia[belong[i]]; } printf("%lld\n", ans); }
|