紫书动规 例题9-13 UVA

来源:互联网 发布:java服务端开发是什么 编辑:程序博客网 时间:2024/05/29 11:45

题目链接:

https://vjudge.net/problem/UVA-1220

题意:

题解:

树形dp: 树的最大独立集问题
d[u][0]:=不选u能得到的最大人数 d[u][0]=sum{max(d[v][0],d[v][1]}
d[u][1]:=选u能得到的最大人数 d[u][1]=sum{d[v][0]}
判断唯一性就是看当前点的孩子是不是不唯一的。初始唯一

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;#define MS(a) memset(a,0,sizeof(a))#define MP make_pair#define PB push_backconst int INF = 0x3f3f3f3f;const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;inline ll read(){    ll x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}//////////////////////////////////////////////////////////////////////////const int maxn = 1e5+10;int n,cnt;map<string,int> mp;string s1,s2;int d[300][2],f[300][2];vector<int> g[300];int ID(string s){    if(!mp.count(s)) mp[s] = cnt++;    return mp[s];}int dp(int u,int k){    d[u][k] = k;    f[u][k] = 1;    for(int i=0; i<(int)g[u].size(); i++){        int v = g[u][i];        if(k == 1){            d[u][k] += dp(v,0);            if(!f[v][0]) f[u][k]=0;        }else{            d[u][k] += max(dp(v,0),dp(v,1));            if(d[v][0]==d[v][1]) f[u][k]=0;            else if(d[v][0]>d[v][1] && !f[v][0]) f[u][k]=0;            else if(d[v][1]>d[v][0] && !f[v][1]) f[u][k]=0;        }    }    return d[u][k];}int main(){    while(scanf("%d",&n) && n){        cnt = 0;        for(int i=0; i<=n; i++) g[i].clear();        mp.clear();        cin >> s1;        ID(s1);        for(int i=1; i<n; i++){            cin >> s1 >> s2;            g[ID(s2)].push_back(ID(s1));        }        int ans = max(dp(0,0),dp(0,1));        cout << ans << " ";        bool unique = true;        if(d[0][0] == d[0][1]) unique=false;        if(d[0][0]>d[0][1] && !f[0][0]) unique=false;        if(d[0][1]>d[0][0] && !f[0][1]) unique=false;        if(unique) puts("Yes");        else puts("No");    }    return 0;}
0 0
原创粉丝点击