(树形dp)poj 3140 Contestants Division

题目
poj3140

题意:
有一张图,可以把其中一条边去掉把图分成两个部分,输出最小的两个部分的值的绝对差。

思路:
记录全图的总价值cnt;
以结点1为根,dp [ i ] 为记录第 i 个结点向下的连通度。
对于其中一个结点 p ,遍历与它有边的结点s1,s2,,,sn,
a n s = min ⁡ i = 1 n ∣ d p [ i ] + v [ i ] − ( c n t − ( d p [ i ] + v [ i ] ) ) ∣ = min ⁡ i = 1 n ∣ ( d p [ i ] + v [ i ] ) ∗ 2 − c n t ∣ ans = \min_{i=1}^{n}|dp[i]+v[i]-(cnt-(dp[i]+v[i]))|=\min_{i=1}^{n}|(dp[i]+v[i])*2-cnt| ans=i=1minndp[i]+v[i](cnt(dp[i]+v[i]))=i=1minn(dp[i]+v[i])2cnt

ps:abs()是int型的,long long 的话要重新写一个关于abs的函数

ps:用vector存图会TLE,要换种结构存图(用链式前向星可以)

ps:删除的是一条边,所有下面这种情况是错误的:
在这里插入图片描述

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector> 
#define DEBUG freopen("_in.txt", "r", stdin); freopen("_out1.txt", "w", stdout);
#define ll long long
using namespace std;
const int MAXN = 1e5 + 10;
const int MAXM = 2e6 + 10;
const ll INF = 9e18;
ll dp[MAXN], v[MAXN];
bool vis[MAXN];
int tree[MAXN], ti;
struct road{
    
    
	int v;
	int next;
}R[MAXM];
void addroad(int u, int v){
    
    
	R[ti].v = v;
	R[ti].next = tree[u];
	tree[u] = ti++;
	R[ti].v = u;
	R[ti].next = tree[v];
	tree[v] = ti++;
}
void dfs(int p){
    
    
	vis[p] = true;
	dp[p] = 0;
	for (int i = tree[p], s; i != -1; i = R[i].next){
    
    
		s = R[i].v;
		if (!vis[s]){
    
    
			dfs(s);
			dp[p] = dp[p] + dp[s] + v[s]; 
		}
	}
}
ll llabs(ll x){
    
    
	return (x < 0) ? -x : x;
}
int main(){
    
    
	int n, m, T = 1;
	while (~scanf("%d%d", &n, &m) && !(n == 0 && m == 0)){
    
    
		ll cnt = 0;
		for (int i = 1; i <= n; i++){
    
    
			scanf("%lld", &v[i]);
			cnt += v[i];
		}
		memset(tree, -1, sizeof(tree));
		ti = 0;
		for (int i = 0, p, s; i < m; i++){
    
    
			scanf("%d%d", &p, &s);
			addroad(p, s);
		}
		memset(vis, false, sizeof(vis));
		dfs(1);
		ll ans = INF;
		for (int i = 1; i <= n; i++){
    
    
			for (int j = tree[i], s; j != -1; j = R[j].next){
    
    
				s = R[j].v;
				ans = min(ans, llabs((dp[s]+v[s]<<1)-cnt));
			}
			if (ans == 0)
				break;
		}
		printf("Case %d: %lld\n", T++, ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ymxyld/article/details/113810143