80pts求调
查看原帖
80pts求调
1088873
Tanliu楼主2024/10/13 21:43
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define int long long
using namespace std;
const int N=1e6+5;
struct node{
	int v,w;
};
vector<node>h[2*N];
deque<int>q;
int n,vis[2*N],sum[2*N],a[2*N],f[2*N],maxn,root,fu,fa[2*N],value[2*N];
void dfs(int u){
	f[u]=0;
	if(!vis[u])vis[u]=1;
	for(int i=0;i<h[u].size();i++){
		int v=h[u][i].v,w=h[u][i].w;
		if(v==fu)continue;
		dfs(v);
		if(vis[v]==root)continue;
		maxn=max(maxn,f[u]+f[v]+w);
		f[u]=max(f[u],f[v]+w);
	}
}
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		int u=i,v,w;
		scanf("%lld %lld",&v,&w);
		fa[i]=v;value[i]=w;
		h[fa[i]].push_back({i,w});
	}
	int answer=0;
	for(int i=1;i<=n;i++){
		if(vis[i]==0){
			int u=i;
			vis[u]=1;
			while(vis[fa[u]]==0){
				vis[fa[u]]=1;
				u=fa[u];
			}
			int v=u,cnt=0;
			root=i+1;
			while(vis[u]!=root){
				a[++cnt]=u;
				vis[u]=root;
				u=fa[u];
			}
			maxn=0;
			fu=v;
			dfs(fu);
			while(!q.empty())q.pop_front();
			for(int j=1;j<=cnt;j++)a[j+cnt]=a[j];
			for(int j=1;j<=2*cnt;j++){
				sum[j]=sum[j-1]+value[a[j-1]];
			}
			int ans=0;
			for(int j=1;j<=2*cnt;j++){
				while(!q.empty()&&j-q.front()+1>cnt)q.pop_front();
				while(!q.empty()&&f[a[j]]-sum[j]>=f[a[q.back()]]-sum[q.back()])q.pop_back();
				if(!q.empty()){
					ans=max(ans,f[a[j]]+sum[j]+f[a[q.front()]]-sum[q.front()]);
				}
				q.push_back(j);
			}
			answer+=max(maxn,ans);
		}
	}
	printf("%lld",answer);
	return 0;
}
2024/10/13 21:43
加载中...