UVA 12452 Plants vs. Zombies HD SP 树形dp(水

来源:互联网 发布:php广告联盟系统 编辑:程序博客网 时间:2024/06/16 15:05

题目链接:点击打开链接

题意:

给定n个点的树[0,n)

开始所有边都是无色。

有3种操作:

1、选一个点染其相连的边 花费100

2、选一个点染其相连的2条边 花费175

3、选一个点染其相连的所有边 花费500

问:

染完所有边的最小花费。边可以重复染,点只能被操作一次。

#include <string>#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <queue>#include <set>#include <map>#include <vector>template <class T>inline bool rd(T &ret) {char c; int sgn;if(c=getchar(),c==EOF) return 0;while(c!='-'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');ret*=sgn;return 1;}template <class T>inline void pt(T x) {    if (x <0) {        putchar('-');        x = -x;    }    if(x>9) pt(x/10);    putchar(x%10+'0');}using namespace std;typedef long long ll;const int N = 10100;const ll inf = 1e10;struct Edge{int to, nex;}edge[N<<1];int head[N], edgenum;void add(int u, int v){Edge E = {v, head[u]};edge[edgenum] = E;head[u] = edgenum++;}void init(){memset(head, -1, sizeof head); edgenum = 0;}int n;ll dp[N][2];/*dp[i][0] : i的父边选了dp[i][1] : i的父边不选*/void up(ll &x, const ll &y){    if(y<x)x = y;}void dfs(int u, int fa){dp[u][0] = dp[u][1] = inf;bool isleaf = true;ll a[3]; memset(a, 0, sizeof a);for(int i = head[u]; ~i; i = edge[i].nex){int v = edge[i].to; if(v == fa)continue;dfs(v, u);a[0] += dp[v][0];a[1] += dp[v][1];a[2] += min(dp[v][0], dp[v][1]);isleaf = false;}if(isleaf){dp[u][0] = 100; dp[u][1] = 0;return; }///////    up(dp[u][0], a[0]+100);    up(dp[u][0], a[2]+500);    up(dp[u][1], a[0]);ll b[3]; b[0] = b[1] = inf;for(int i = head[u]; ~i; i = edge[i].nex){int v = edge[i].to; if(v == fa)continue;up(dp[u][0], a[0]-dp[v][0]+dp[v][1] + 175);b[2] = -dp[v][0]+dp[v][1];sort(b, b+3);}up(dp[u][1], a[0]+b[0]+b[1]+175);}void input(){init();rd(n);for(int i = 1, u, v; i < n; i++){rd(u); rd(v);add(u, v); add(v, u);}}int main() {int T;scanf("%d", &T);while(T--){input();dfs(0, 0);//for(int i = 0; i < n; i++)printf("%d: %lld %lld\n", i, dp[i][0], dp[i][1]);printf("$%lld\n", min(dp[0][0], dp[0][1]));}return 0;}/*99100 10 23 22 43 53 63 73 83 960 10 20 33 44 570 11 22 32 42 55 650 10 20 33 450 10 20 30 470 10 20 30 40 50 670 10 21 33 45 25 6*/


0 1
原创粉丝点击