不明原因60分,求助
查看原帖
不明原因60分,求助
175011
rfsfreffr楼主2021/10/18 11:56
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[1000001];
int vis[1000001];
int color[1000001];
int tot;
int cnt;
int fa[1000001];
int root[1000001];
vector<int>b[1000001];
int dp[1000001][2];// 点i选与不选 
int g[1000001][2];// 在环上跑 
void dfs(int x) {
	vis[x]=1;
	color[x]=tot;
	for(int i=0 ; i<b[x].size(); i++) {
		int v=b[x][i];
		if(vis[v]==0) {
			dfs(v);
		} else if(vis[v]==1&&color[v]==tot) {
			int p=x;
			
			while(1) {
				root[++cnt]=p;
				if(p==v) return ;
				
				p=fa[p];
				
			} 
		}
	}
}
void dfs2(int x) {
	dp[x][0]=0;
	dp[x][1]=a[x];
	for(int i=0; i<b[x].size(); i++) {
		int v=b[x][i];
		if(vis[v]) continue;
		
		dfs2(v);
		dp[x][1]+=dp[v][0];
		dp[x][0]+=max(dp[v][1],dp[v][0]);
	}
}
void dfs3(int x) {
	g[x][0]=dp[x][0];
	g[x][1]=dp[x][1];
	vis[x]=0;
	for(int i=0; i<b[x].size(); i++) {
		int v=b[x][i];
		if(vis[v]==0) continue;
		dfs3(v);
		g[x][1]+=g[v][0];
		g[x][0]+=max(g[v][1],g[v][0]);
	}
	
}
signed main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		scanf("%lld%lld",&a[i],&fa[i]);
		b[fa[i]].push_back(i);
	}
	for(int i=1; i<=n; i++) {
		if(vis[i]==0) {
			tot++;
			dfs(i);
		}
	} 
	memset(vis,0,sizeof(vis));
	for(int i=1; i<=cnt; i++) vis[root[i]]=1;
	for(int i=1; i<=cnt; i++) {
		dfs2(root[i]);
	}
	int ans=0;
	for(int i=1; i<=cnt; i++) {
		if(vis[root[i]]==1) {
			dfs3(root[i]);
			ans+=max(g[root[i]][0],g[root[i]][1]);
		}
	}
	cout<<ans<<endl;
	return 0;
}
/*
20
0 2
0 3
0 4
0 1
0 3
0 3
0 5
0 5
0 6
0 2
0 10
0 10
0 1
0 1
0 2
0 2
0 2
0 4
0 18
0 19


*/

我感觉是树形dp完后在环上跑的dp炸了,只对了前6个点(n<=100 ?).但自己不会改

2021/10/18 11:56
加载中...