萌新求教:90pts WA on #11/15
查看原帖
萌新求教:90pts WA on #11/15
121027
Spasmodic楼主2020/9/20 00:06

rt

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2000005;
namespace Solution{
	ll n,cnt,hd[N];
	struct edge{ll t,w,nxt;}es[N<<1];
	void add(ll u,ll v,ll w){es[++cnt]=(edge){v,w,hd[u]},hd[u]=cnt;}
	void init(){
		scanf("%lld",&n);
		for(ll i=1,v,l;i<=n;i++){
			scanf("%lld%lld",&v,&l);
			add(i,v,l),add(v,i,l);
		}
	}
	bool vst[N]; 
	ll tot,num,dfn[N],f[N],dis[N],l[N],s[N];
	void tarjan(ll u){//第一步,找环 
		dfn[u]=++num;
		for(ll i=hd[u],v;i;i=es[i].nxt)
			if((v=es[i].t)==f[u])continue;
			else if(dfn[v]){
				if(dfn[v]<dfn[u])continue;
				l[++tot]=v,s[tot]=0,vst[v]=1;
				for(;v!=u;v=f[v])l[++tot]=f[v],s[tot]=s[tot-1]+dis[v],vst[f[v]]=1;
				s[tot+1]=s[tot]+es[i].w;
			}else f[v]=u,dis[v]=es[i].w,tarjan(v);
	}
	ll ma,d[N];
	void dfs(ll u){//第二步,求直径
		for(ll i=hd[u],v;i;i=es[i].nxt)
			if(!vst[v=es[i].t])
				vst[v]=1,dfs(v),ma=max(ma,d[u]+d[v]+es[i].w),d[u]=max(d[u],d[v]+es[i].w);
	}
	ll a[N],q[N],L,R;
	ll dp(){//第三步,单调队列dp 
		ll ret=0;
		for(ll i=tot+2;i<=(tot<<1);i++)s[i]=s[i-1]+dis[l[i-tot-1]];
		for(ll i=1;i<=tot;i++)a[i]=a[i+tot]=d[l[i]];
		for(ll i=1,L=R=0;i<=(tot<<1);i++){
			while(L<R&&i-q[L]>=tot)L++;
			ret=max(ret,a[i]+s[i]+a[q[L]]-s[q[L]]);
			while(L<R&&a[q[R-1]]-s[q[R-1]]<=a[i]-s[i])R--;
			q[R++]=i;
		}
		return ret;
	}
	ll calcdist(ll u){
		ll ret=0;
		tot=ma=0;
		tarjan(u);
		for(ll i=1;i<=tot;i++)ma=0,dfs(l[i]),ret=max(ret,ma);
		ret=max(ret,dp());
		return ret;
	}
	ll solve(){
		ll ret=0;
		for(ll i=1;i<=n;i++)if(!vst[i])ret+=calcdist(i);
		return ret;
	}
} 
int main(){
	Solution::init();
	printf("%lld\n",Solution::solve());
	return 0;
}
2020/9/20 00:06
加载中...