思路没用题解里的思路,是先求去掉环上的其中一条边后的整棵树的直径,再求必须经过其中一条边的情况下的最长路径(这里用了类似题解的方法)
请问是思路错了还是代码有锅
#include<bits/stdc++.h>
using namespace std;
struct node
{
int u,v,nt;
long long w;
};
node e[3000020];
int h[3000003],tot,opp[3000003];
void add(int x,int y,long long z)
{
tot++;
e[tot].u=x;
e[tot].v=y;
e[tot].w=z;
e[tot].nt=h[x];
h[x]=tot;
}
long long dis[3000003],f[3000003];
int fa[3000003],tag[3000003],cnt,top,a[3000003];
long long ans;
bool vis2[3000003],vis[3000003];
void count(int x,int pr){
vis[x]=1;
for(int i=h[x];i;i=e[i].nt)
if(!vis[e[i].v]){
fa[e[i].v]=x;
count(e[i].v,i);
f[x]=max(f[x],dis[x]+dis[e[i].v]+e[i].w);
dis[x]=max(dis[x],dis[e[i].v]+e[i].w);
ans=max(ans,f[x]);
}
else
if(opp[i]!=pr&&!top) {
tag[cnt]=i;
a[++top]=x;
vis2[x]=1;
while(a[top]!=e[i].v){
a[top+1]=fa[a[top]];
vis2[a[top+1]]=1;
top++;
}
}
}
long long dis2[3000003],sum[3000003],maxn2[3000003];
void dfs2(int x){
vis2[x]=1;
for(int i=h[x];i;i=e[i].nt)
if(!vis2[e[i].v]){
dfs2(e[i].v);
dis2[x]=max(dis2[e[i].v]+e[i].w,dis2[x]);
}
}
void count2(){
sum[1]=0;
maxn2[0]=-(1ll<<62);
for(int i=1;i<=top;i++){
sum[i+1]=sum[i]+dis[a[i+1]]-dis[a[i]];
dfs2(a[i]);
maxn2[i]=max(maxn2[i-1],sum[i]+dis2[a[i]]);
}
for(int i=top;i>=2;i--){
ans=max(ans,maxn2[i-1]+dis2[a[i]]+e[tag[cnt]].w+sum[top]-sum[i]);
}
}
int n,k;
long long res=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int y;
long long z;
scanf("%d%lld",&y,&z);
add(i,y,z);
opp[tot]=tot+1;
add(y,i,z);
opp[tot]=tot-1;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
ans=0;
cnt++;
top=0;
count(i,0);
count2();
res+=ans;
}
}
printf("%lld",res);
}