萌新刚学OI,求助基环树
查看原帖
萌新刚学OI,求助基环树
135485
Push_Y楼主2021/3/2 22:30

RT

完完全全的按照第一篇题解写的,样例输出来是25.我感觉写的是对的于是交了一发,80分。但不知道样例这个哪里出问题了

#include <bits/stdc++.h>
#define int long long
using namespace std;

inline int gin(){
	char c=getchar();
	int s=0,f=1;
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		s=(s<<3)+(s<<1)+(c^48);
		c=getchar();
	}
	return s*f;
}

const int N=1e6+5;
int to[N<<1],we[N<<1],ne[N<<1],head[N];
int n,tot,zmz,top,st[N],s[N],gy,ans,ans1,ans2;
int q[N],d[N],f[N<<1];
bool co[N],vis[N];

inline void add(int u,int v,int w){
	to[++tot]=v;
	we[tot]=w;
	ne[tot]=head[u];
	head[u]=tot;
}

bool dfs(int u,int fa){
	if(vis[u]==1){
		zmz=u,st[++top]=u,co[u]=1;
		return 1;
	}
	vis[u]=1;
	for(int i=head[u];i;i=ne[i]){
		int v=to[i];
		if(v==fa)continue;
		if(dfs(v,u)){
			if(u==zmz){
				s[gy-1]=s[gy]-we[i];
				return 0;
			}
			st[++top]=u,co[u]=1,s[top]=s[top-1]+we[i];
			return 1;
		}
	}
	return 0;
}

void dp(int u){
	co[u]=1;
	for(int i=head[u];i;i=ne[i]){
		int v=to[i];
		if(co[v])continue;
		dp(v);
		ans=max(ans,d[u]+d[v]+we[i]);
		d[u]=max(d[u],d[v]+we[i]);
	}
}

inline long long solve(int rt){
	gy=top+1,ans1=0,ans2=0;
	dfs(rt,0);
	for(int i=gy;i<=top;i++){
		ans=0;
		dp(st[i]);
		ans1=max(ans1,ans);
		f[i+top-gy+1]=f[i]=d[st[i]];
		s[i+top-gy+1]=s[i+top-gy]+s[i]-s[i-1];
	}
	int l=0,r=0;
	for(int i=gy;i<=2*top-gy+1;i++){
		while(l<=r && q[l]<=i-(top-gy+1))l++;
		if(l<=r)ans2=max(ans2,f[i]+f[q[l]]+s[i]-s[q[l]]);
		while(l<=r && f[q[r]]-s[q[r]]<=f[i]-s[i])r--;
		q[++r]=i;
	}
	return max(ans1,ans2);
}

signed main(){
	n=gin();
	for(int i=1;i<=n;i++){
		int v=gin(),w=gin();
		add(i,v,w);add(v,i,w);
	}
	long long sum=0;
	for(int i=1;i<=n;i++){
		if(co[i])continue;
		sum+=solve(i);
	}
	printf("%lld\n",sum);
	return 0;
}

2021/3/2 22:30
加载中...