POJ_3342_Party at Hali-Bula_树形DP
POJ_3342_Party at Hali-Bula_树形DP
题意:直接上司和本人不能同时参加,求最多参加人数,并回答是否唯一解。
分析:常规树形DP,需要再维护一下选/不选当前点取得最大值时是否为唯一解。
就是在转移时判断该状态是从哪转移过来的,最后答案同理。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 220 #define mem(x) memset(x,0,sizeof(x)) int head[N],to[N<<1],nxt[N<<1],flg,cnt,n; int f[N],g[N],h[N],d[N]; char ch[N][N],a[N],b[N]; void add(int u,int v) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; } void dfs(int x,int y) { f[x]=1;d[x]=h[x]=1; for(int i=head[x];i;i=nxt[i]) { if(to[i]!=y) { dfs(to[i],x); f[x]+=g[to[i]]; g[x]+=max(g[to[i]],f[to[i]]); if(g[to[i]]>f[to[i]]&&d[to[i]]==0)d[x]=0; else if(g[to[i]]<f[to[i]]&&h[to[i]]==0)d[x]=0; else if(g[to[i]]==f[to[i]])d[x]=0; if(d[to[i]]==0)h[x]=0; } } } int main() { while(scanf("%d",&n)) { if(!n)break; mem(d);mem(h);mem(f);mem(g);mem(head); cnt=0;flg=0; scanf("%s",ch[1]); int now=1; for(int i=1;i<n;i++) { scanf("%s%s",a,b); int na=0,nb=0; for(int j=1;j<=now;j++) { if(strcmp(ch[j],a)==0) { na=j; } if(strcmp(ch[j],b)==0) { nb=j; } } if(!na) { na=++now; strcpy(ch[now],a); } if(!nb) { nb=++now; strcpy(ch[now],b); } add(na,nb); add(nb,na); } dfs(1,0); printf("%d ",max(f[1],g[1])); if(f[1]==g[1])flg=1; if(f[1]>g[1]&&h[1]==0)flg=1; if(f[1]<g[1]&&d[1]==0)flg=1; puts(flg?"No":"Yes"); } }