95分TLE求助
查看原帖
95分TLE求助
110973
彩虹猫楼主2021/10/20 13:05

测试点信息:

point

code:

#include<bits/stdc++.h>
#define Maxn 1000005
#define ll long long
using namespace std;
inline ll read()
{
	ll x=1,f=0;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')x=-1;c=getchar();}
	while(c>='0'&&c<='9'){f=f*10+c-'0';c=getchar();}
	return x*f;
}
inline void out(ll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>=10) out(x/10);
	putchar(x%10+'0');
}
inline void print(ll x,char c)
{
	out(x),putchar(c);
}
deque<ll>q,num;
bool Incircle[Maxn];
ll End[2*Maxn],Next[2*Maxn],Len[2*Maxn],Last[Maxn];
ll circle[2*Maxn],dfn[Maxn],fa[Maxn];
ll dp1[Maxn],dp2[Maxn],dep[Maxn*2],s[Maxn*2];
ll prel[Maxn];
ll n,cnt,stop,Index,tmp;
void addedge(ll x,ll y,ll z)
{
	End[++cnt]=y;
	Len[cnt]=z;
	Next[cnt]=Last[x];
	Last[x]=cnt;
}
void init()
{
	memset(circle,0,sizeof(circle));
	memset(Incircle,0,sizeof(Incircle));
	memset(fa,0,sizeof(fa));
	memset(dep,0,sizeof(dep));
	memset(s,0,sizeof(s));
	q.clear(); num.clear();
}
void Findcircle(ll u)
{
//	prllf("u=%d\n",u);
	dfn[u]=(++Index);
	for(ll i=Last[u];i;i=Next[i])
	{
		ll v=End[i];
		if(v==fa[u]) continue;
		if(dfn[v])
		{
			if(dfn[v]<dfn[u]) continue;
			while(v!=u) circle[++stop]=v,Incircle[v]=1,s[stop+1]=s[stop]+prel[v],v=fa[v];
			circle[++stop]=u;
			Incircle[u]=1;
			s[stop+1]=s[stop]+Len[i];
		}
		else fa[v]=u,prel[v]=Len[i],Findcircle(v);
	}
}
void dfs(ll u,ll fa)
{
//	prllf("u=%d fa=%d\n",u,fa);
	dp1[u]=dp2[u]=0;
	for(ll i=Last[u];i;i=Next[i])
	{
		ll v=End[i];
		if(v==fa) continue;
		if(Incircle[v]==1) continue; 
		dfs(v,u);
		ll t=(ll)dp1[v]+Len[i];
		if(t>dp1[u]) dp2[u]=dp1[u],dp1[u]=t;
		else if(t>dp2[u]) dp2[u]=t;
	}
	tmp=max(tmp,dp1[u]+dp2[u]);
}
ll solve(ll u)
{
//	printf("start=%lld\n",u);
	init();
	stop=Index=0;
	Findcircle(u);
//	printf("stop=%d\n",stop);
//	for(ll i=1;i<=stop;i++) prllf("circle[%d]=%d\n",i,circle[i]);
	ll ans1=0;
	for(ll i=1;i<=stop;i++)
	{
		tmp=0;
		dfs(circle[i],0);
		ans1=max(ans1,tmp);
	}
	ll ans2=0;
	if(stop==2)
	{
		for(ll i=Last[circle[1]];i;i=Next[i])
		{
			if(End[i]==circle[2]) ans2=max(ans2,Len[i]);
		}
		return max(ans1,ans2+dp1[circle[1]]+dp1[circle[2]]);
	}
	for(ll i=stop+1;i<=2*stop;i++) circle[i]=circle[i-stop];
	for(ll i=stop+1;i<=2*stop-1;i++) s[i+1]=s[i]+(s[i+1-stop]-s[i-stop]);
	for(ll i=1;i<=2*stop;i++) dep[i]=dp1[circle[i]];
	//q1:dep[i]-s[i]  q2:dep[j]+s[j]
	for(ll i=1;i<=2*stop;i++)
	{
		while(!q.empty()&&num.front()<=i-stop) q.pop_front(),num.pop_front();
		if(!q.empty()) ans2=max(ans2,dep[i]+s[i]+q.front());
		while(!q.empty()&&q.back()<=dep[i]-s[i]) q.pop_back(),num.pop_back();
		q.push_back(dep[i]-s[i]);
		num.push_back(i);
	}
//	printf("ans1=%d ans2=%d\n",ans1,ans2);
	return max(ans1,ans2);
}
int main()
{
	n=read();
	for(ll i=1;i<=n;i++)
	{
		ll x=read(),y=read();
		addedge(i,x,y);
		addedge(x,i,y);
	}
	ll ans=0;
	for(ll i=1;i<=n;i++)
	{
		if(!dfn[i]) ans+=solve(i);
	}
	print(ans,'\n');
	return 0;
}
2021/10/20 13:05
加载中...