Main idea: Give you a pile of base-ring trees, find the diameter and sum of these base-ring trees.
Solution: Find the diameter of the base ring tree: Discuss whether the diameter passes through the ring or not. For the diameter that does not pass through the ring, it is the diameter of the subtree where the point on the ring is the root node, and take the maximum value. Diameter of the passing ring: Obviously, disdisdis dis is the longest distance from each point on the ring to the point in its subtree. The replication of the ring is doubled, and then every point uuu on the ring is enumerated as the end point. The maximum value of disv sumvdis_v sum_vdisv sumv is found by monotone queue optimization, and ans=max(ans,disu+disv+sumu sumv) ans = max (sumv, + + + +) - (ans=max).
(The nausea is that this problem has blocked the recursive method, and the burdock can not be written, only the recursive version of the code, to be filled)
Recursive buckle ring:
#include<bits/stdc++.h> using namespace std; #define pii pair<int,int> #define fir first #define sec second const int maxn = 1e6 + 10; vector<pii> g[maxn]; typedef long long ll; int pot[2 * maxn],w[2 * maxn],cnt,dfn[maxn],sz; ll dp[maxn][2]; int vis[maxn],d[maxn],f[maxn]; int n; ll q[2 * maxn],sum[2 * maxn]; int id[2 * maxn],top,rear; void dfs(int u,int wi,int fa) { dfn[u] = ++sz; bool t = false; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i].fir,val = g[u][i].sec; if(v == fa && val == wi && !t) { t = true; continue; } if(!dfn[v]) { d[v] = val; f[v] = u; dfs(v,val,u); } else if(dfn[v] < dfn[u]) continue; else if(dfn[v] > dfn[u]) { for(int p = v; p != u; p = f[p]) { //Border power should be kept in correspondence, so one bit should be moved. pot[++cnt] = p; w[cnt + 1] = d[p]; } pot[++cnt] = u; w[1] = val; continue; } } } void dfs2(int u,int fa,ll &ans) { dp[u][0] = dp[u][1] = 0; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i].fir,val = g[u][i].sec; if(v == fa || vis[v]) continue; dfs2(v,u,ans); if(dp[v][0] + val > dp[u][0]) { dp[u][1] = dp[u][0]; dp[u][0] = dp[v][0] + val; } else if(dp[v][0] + val > dp[u][1]) { dp[u][1] = dp[v][0] + val; } } ans = max(ans,dp[u][0] + dp[u][1]); } int main() { scanf("%d",&n); for(int i = 1; i <= n; i++) { int u,v; scanf("%d%d",&u,&v); g[i].push_back(pii(u,v)); g[u].push_back(pii(i,v)); } ll res = 0,ans = 0; for(int i = 1; i <= n; i++) { if(!dfn[i]) { ans = cnt = 0;dfs(i,0,0); sum[0] = top = rear = 0; for(int i = 1; i <= cnt; i++) vis[pot[i]] = 1; for(int i = 1; i <= cnt; i++) pot[i + cnt] = pot[i],w[i + cnt] = w[i]; for(int i = 1; i <= cnt; i++) dfs2(pot[i],0,ans); for(int i = 1; i <= 2 * cnt; i++) sum[i] = sum[i - 1] + w[i]; int cur = 1; for(int i = 1; i <= 2 * cnt; i++) { while(cur < i) { while(rear > top && q[rear] <= dp[pot[cur]][0] - sum[cur]) rear--; q[++rear] = dp[pot[cur]][0] - sum[cur]; id[rear] = cur; while(top < rear && id[top + 1] < i - cnt + 1) top++; cur++; } if(top < rear && id[top + 1] != i) ans = max(ans,q[top + 1] + dp[pot[i]][0] + sum[i]); } res += ans; } } printf("%lld\n",res); return 0; }