基环树直径 90pts,WA on15,18 求助
查看原帖
基环树直径 90pts,WA on15,18 求助
128591
Refined_heart楼主2021/8/31 13:07

答案偏小的样子/kel

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int N=1e6+10;
ll sum[N<<1],val[N];
int head[N],tot,n,m;
struct E{int nxt,to,dis;}e[N<<1];
int st[N],top,vis[N],num,cir[N<<1],cnt;
inline int Max(int x,int y){return x>y?x:y;}
//inline ll Max(ll x,ll y){return x>y?x:y;}
vector<int>Cir[N];
void Get(int node,int x){
	int i;
	for(i=top;i&&st[i]!=x;--i)Cir[node].push_back(st[i]),st[i]=0;
	Cir[node].push_back(x);st[i]=0;
}
void Find_Circle(int x,int fa,int node){
//	if(!Cir[node].empty())return;
	vis[x]=1;st[++top]=x;
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==fa){continue;}
		if(vis[j]&&Cir[node].empty()){Get(node,j);}
		if(!vis[j])Find_Circle(j,x,node);
	}
	--top;
}
inline void link(int u,int v,int w){
	e[++tot]=(E){head[u],v,w};
	head[u]=tot;
}
// char buf[1<<21],*p1=buf,*p2=buf;
#define gc() getchar()//(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read(){
	int s=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch)){
		s=s*10+ch-'0';
		ch=gc();
	}
	return s;
}
ll ans=-1;
ll f[N][2];
void Dp(int x,int fa){
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==fa)continue;
		if(vis[j])continue;
		Dp(j,x);
		int j1=f[j][1]+e[i].dis;
		int j0=f[j][0]+e[i].dis;
		if(j0>=f[x][0]){
			f[x][1]=f[x][0];
			f[x][0]=j0;
		}
		else if(j0>f[x][1])f[x][1]=j0;
		else if(j1>f[x][1])f[x][1]=j1;
	}
}
int getval(int x,int v){
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==v)return e[i].dis;
	}
	return -1;
}
int q[N<<1],tail,Head;
ll dp[N<<1];
void solve(int pos,ll &R){
//	printf("%d:\n",pos);
//	for(int i=1;i<=cnt;++i)printf("(%d %d) ",cir[i],val[cir[i]]);
//	puts("");
	tail=0;Head=1;
	q[++tail]=1;dp[1]=val[cir[1]];
	//len[i]
	for(int i=1;i<=cnt;++i)cir[i+cnt]=cir[i];
	cnt<<=1;
	for(int i=2;i<=cnt;++i){
		int v=getval(cir[i-1],cir[i]);
		sum[i]=sum[i-1]+v;
	}
//	for(int i=1;i<=cnt;++i)printf("%d ",sum[i]);
//	puts("");
	for(int i=2;i<=cnt;++i){
		while(Head<=tail&&q[Head]<i-(cnt/2)+1)++Head;
		
		dp[i]=val[cir[i]]+sum[i]-sum[q[Head]]+val[cir[q[Head]]];
//		printf("zy:(%d %d) f[%d]=%d\n",q[Head],i,i,dp[i]);
		while(Head<=tail&&val[cir[i]]-sum[i]>=val[cir[q[tail]]]-sum[q[tail]])--tail;
		q[++tail]=i;
	}
//	for(int i=1;i<=cnt;++i)printf("%d ",dp[i]);
	ll T=-1;
	for(int i=1;i<=cnt;++i)T=Max(T,dp[i]);
	R+=T;
	for(int i=1;i<=cnt;++i)sum[i]=0;
	for(int i=1;i<=cnt;++i)q[i]=0;
}
struct EEE{
	int u,v,w;
}Edge[N];
inline bool cmp(EEE x,EEE y){
	if(x.u==y.u&&x.v==y.v)return x.w>y.w;
	return x.u==y.u?x.v<y.v:x.u<y.u;
}
signed main(){
//	freopen("358.in","r",stdin);
//	freopen("358.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i){
		int a=read(),L=read();
		int u=i,v=a;
		if(u>v)swap(u,v);
		Edge[i]=(EEE){u,v,L};
//		link(i,a,L);link(a,i,L);
//		printf("(%d %d)\n",i,a);
	}
	sort(Edge+1,Edge+n+1,cmp);
	
	for(int i=1;i<=n;++i){
		int u=Edge[i].u;
		int v=Edge[i].v;
		if(u==Edge[i-1].u&&v==Edge[i-1].v)continue;
		link(u,v,Edge[i].w);
		link(v,u,Edge[i].w);
//		printf("(%d %d %d)\n",u,v,mp[u][v]);
	}
	for(int i=1;i<=n;++i){
		if(!vis[i]){
			++num;
			top=0;
			Find_Circle(i,0,num);
			if(Cir[num].empty())Cir[num].push_back(i);
		}
	}
//	for(int i=1;i<=num;++i){
//		printf("%d:\n",i);
//		for(auto v:Cir[i])printf("%d ",v);
//		puts("");
//	}
	for(int i=1;i<=n;++i)vis[i]=0;
	for(int i=1;i<=num;++i){
		for(auto v:Cir[i])
			vis[v]=1;
	}
		
	for(int i=1;i<=n;++i){
		if(!vis[i])continue;
		Dp(i,0);
		val[i]=f[i][0];
//		printf("%d:(%d %d)\n",i,f[i][0],f[i][1]);
	}
	ll Res=0;
	for(int i=1;i<=num;++i){
		ll mx=-1;
		for(auto v:Cir[i])mx=Max(mx,f[v][0]+f[v][1]);
		Res+=mx;
	}
	ans=Max(Res,ans);
//	cout<<ans<<endl;
	ll res=0;
	for(int i=1;i<=num;++i){
		int L=Cir[i].size();
		top=0;
		if(L<=1){
			ll mx=-1;
			for(auto v:Cir[i])mx=Max(mx,f[v][0]+f[v][1]);
			res+=mx;
			continue;
		}
		cnt=0;
		for(auto v:Cir[i])cir[++cnt]=v;
		solve(i,res);
//		printf("(%d %d)\n",i,V[i]);
	}
	ans=Max(ans,res);
//	cout<<res<<endl;
	printf("%lld\n",ans);
	return 0;
}
2021/8/31 13:07
加载中...