TLE,MLEon#3,15,求调
查看原帖
TLE,MLEon#3,15,求调
553849
wangmaocheng楼主2023/12/4 22:02

RT

//#pragma GCC optimize(2)//O2,洛谷要关
#include <iostream>

#include <cstdio>
#include <algorithm>
#include <bits/stdc++.h>
#define str string
#define ll long long
#define db double
using namespace std;
const int N=1e6+10,M=1000,K=1.5e6;
int n;
ll ans;
vector<int>e[N],siz[N],id[N];
int dfn[N],low[N],cnt;//用tarjan找环的尝试 
int scc[N];
bool book[N];
vector<int>ring[M];
int m,has[N];
int t[N],nxt[N];
int q[K],head,tail;
ll lenth[N],zhi[N];
ll num[K],sum[K];
void findhuan(int x,int fa)
{
	cnt++;
	dfn[x]=cnt;
	low[x]=cnt;
	for(int i=0;i<e[x].size();i++)
	{
		int y=e[x][i];
		int idx=id[x][i];
		if(idx==fa)continue;
		if(dfn[y])
		{
			low[x]=min(low[x],dfn[y]);
			continue;
		}
		findhuan(y,idx);
		low[x]=min(low[x],low[y]);
	}
	scc[low[x]]++;
}
void findlen(int x)
{
	ll maxn=0,midn=0;
	book[x]=1;
	for(int i=0;i<e[x].size();i++)
	{
		int y=e[x][i];
		int sz=siz[x][i];
		if(book[y])continue;
		findlen(y);
		zhi[x]=max(zhi[x],zhi[y]);
		ll l=lenth[y]+sz;
		if(l>maxn)
		{
			midn=maxn;
			maxn=l;
		}
		else if(l>midn)
		{
			midn=l;
		}
	}
	zhi[x]=max(zhi[x],maxn+midn);
	lenth[x]=maxn;
}
signed main()
{
//	freopen("in.in","r",stdin);
//	freopen("1.out","w",stdout);
    ios::sync_with_stdio(false);
	cin>>n;
	for(int u=1;u<=n;u++)
	{
		int v,w;
		cin>>v>>w;
		nxt[u]=v;
		t[u]=w;
		e[u].push_back(v);
		e[v].push_back(u);
		id[u].push_back(u);
		id[v].push_back(u);
		siz[u].push_back(w);
		siz[v].push_back(w);
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])
		{
			findhuan(i,0);
		}
	}
//	for(int i=1;i<=n;i++)
//	{
//		cout<<low[i]<<' ';
//	}
	for(int x=1;x<=n;x++)
	{
		if(scc[low[x]]==1)continue;
		if(has[low[x]]==0)
		{
			m++;
			has[low[x]]=m;
		}
		book[x]=1;
		ring[has[low[x]]].push_back(x);
	}
//	前面通过tarjan算法找环+缩点 
	for(int i=1;i<=m;i++)
	{
		for(auto x:ring[i])
		{
			findlen(x);
//			cout<<x<<' '<<lenth[x]<<'\n';
		}
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=0;j<ring[i].size()-1;j++)
		{
			ring[i][j+1]=nxt[ring[i][j]];
		}
	}
//	for(int i=1;i<=m;i++)
//	{
//		cout<<i<<':';
//		for(auto y:ring[i])
//		{
//			cout<<y<<' ';
//		}
//		cout<<'\n';
//	}
	for(int i=1;i<=m;i++)
	{
		head=tail=0;
		ll res=0;
		int s=ring[i].size();
		for(int j=0;j<s;j++)
		{
			num[j+1]=ring[i][j];
			num[j+1+s]=ring[i][j];
			res=max(res,zhi[num[j+1]]);
		}
		for(int j=1;j<=2*s;j++)
		{
			sum[j]=sum[j-1]+t[num[j]];
//			cout<<num[j]<<' '<<sum[j]<<'\n';
		}
		for(int j=1;j<=2*s;j++)
		{
			if(q[head]+s<=j&&head<tail)head++;
			if(head<tail)
			res=max(res,lenth[num[q[head]]]+lenth[num[j]]+sum[j-1]-sum[q[head]-1]);
			while(head<tail&&lenth[num[q[tail-1]]]-sum[q[tail-1]-1]<lenth[num[j]]-sum[j-1])tail--;
			q[tail++]=j;
		}
		ans+=res;
	}
	cout<<ans;
    return 0;
}
/*

*/
2023/12/4 22:02
加载中...