HDU 3660 Alice and Bob's Trip【树形DP】
题意: Alice 和 Bob在一颗树上轮流走,知道了每条边的长度,Alice想走的权值和尽量小,Bob想走尽量大,同时所走的权值和必须在[L, R]这个给定的区间内,
Bob先走,问Bob 能得走的最大的权值和是多少? 如果还能走,Alice就不能停下来。
分析: dp[r] 表示到节点 r 的最优值,从叶子递归,Alice选每次最小走,Bob选最大走,d[u]表示从跟到节点u的距离,
d[u]+dp[t]+cost(u, t) 必须在[L, R]之间才转移
#include<stdio.h> #include<string.h> #define INF 0x1f1f1f1f #define max(a,b)(a)>(b)?(a):(b) #define min(a,b)(a)<(b)?(a):(b) #define clr(x)memset(x,0,sizeof(x)) #define maxn 500005 struct node { int to,next,w; }e[10000000]; int tot; int head[maxn]; void add(int s,int t,int wi) { e[tot].to=t; e[tot].w=wi; e[tot].next=head[s]; head[s]=tot++; } int n,L,R; int dp[maxn]; int d[maxn]; void dfs(int r,int p) { if(d[r]>R) { dp[r]=0; return; } dp[r]=p?-1:INF; int flag=1,i,k; for(i=head[r];i;i=e[i].next) { flag=0; k=e[i].to; d[k]=d[r]+e[i].w; dfs(k,!p); if(dp[k]==-1||dp[k]==INF) continue; int tmp=d[r]+dp[k]+e[i].w; if(tmp>=L&&tmp<=R) { if(p) dp[r]=max(dp[r],dp[k]+e[i].w); else dp[r]=min(dp[r],dp[k]+e[i].w); } } if(flag) dp[r]=0; } int main() { int i; while(scanf("%d%d%d",&n,&L,&R)!=EOF) { tot=1; clr(head); int a,b,c; for(i=1;i<n;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); } clr(d); dfs(0,1); if(dp[0]>=L&&dp[0]<=R) printf("%d\n",dp[0]); else printf("Oh,my god!\n"); } return 0; }