70分,求改
查看原帖
70分,求改
890233
gmx0424楼主2023/10/3 20:22
#include<bits/stdc++.h>
using namespace std;
const int M = 1000005;
long long n, dp[M][2];//dp[i][1/0] : 第i号人选和不选 
int a[M]; // 记录每个战士的战斗力 
struct node {
	int to, next;
}g[2 * M];
long long ans;
int cnt, head[M];
void add(int u, int v) {
	g[cnt].to = v;	
	g[cnt].next = head[u];
	head[u] = cnt;
	++cnt;
}
bool vis[M]; 
int  p1, p2, edge;//记录环上的两个端点 和边 
void dfs( int u, int fa) {//找环 
	vis[u] = true; //标记已经访问过,方便下面找环
	for (int i = head[u]; i; i = g[i].next) {
		int to = g[i].to;
		if (to == fa ) {//不能是自己父亲 
			continue;
		}
		if (!vis[to]) {//没有访问过这个点 
			dfs(to, u);//继续dfs 
		} else {//如果访问过了,证明有环 记录下来 
			p1 = to;
			p2 = u;
			edge = (i ^ 1); 
		}
	} 
}
void dfs2(int u, int fa) {
		dp[u][1] = a[u];
		dp[u][0] = 0;
		for (int i = head[u]; i; i = g[i].next ) {
			int to = g[i].to;
			if (to == fa || i == edge || i == (1 ^ edge)) {
				continue;
			}
			dfs2(to, u);
			dp[u][0] += max (dp[to][0], dp[to][1]); // u不去,仇人可以去,可以不去 
			dp[u][1] += dp[to][0]; // u去,那么仇人不能去 
		}
}	
int main () {
	cin >> n;
	for (int i = 1; i <= n; i++ ) {
		int num, v;
		cin >> num >> v;
		a[i] = num; 
		add(i, v );
		add(v, i );
	} 
	for (int i = 1; i <= n; i++ ) {
		if (vis[i] == 0) {
			dfs(i, -1);	
			long long tmp = -100000;		
		dfs2(p1, -1);
		tmp = max (tmp, dp[p1][0]);		
		dfs2(p2, -1);
		ans += max (tmp, dp[p2][0]);
		}	
	}
	cout << ans << "\n";
	return 0; 
}
2023/10/3 20:22
加载中...