uva 1220

来源:互联网 发布:python 登录知乎 编辑:程序博客网 时间:2024/06/06 03:16

#include <iostream>#include <cstdio>#include <map>#include <vector>#include <cstring>using namespace std;const int maxn=2e2+5;vector<int> G[maxn];map<string,int> id;//用map给字符串标号int dp[maxn][2],n,cnt;bool f[maxn][2];string s1,s2;void inition(){    memset(f,true,sizeof(f));    memset(dp,0,sizeof(dp));    for(int i=0; i<=n; i++) G[i].clear();    id.clear();    cnt=0;}void input(){    cin >> s1;    id[s1]=++cnt;    for(int i=0; i<n-1; i++)    {        cin >> s1 >> s2;        if(!id[s1]) id[s1]=++cnt;        if(!id[s2]) id[s2]=++cnt;        G[id[s2]].push_back(id[s1]);    }}void output(){    if(dp[1][0]==dp[1][1]) printf("%d No\n",dp[1][1]);    else if(dp[1][0]<dp[1][1]) printf("%d %s\n",dp[1][1],f[1][1]?"Yes":"No");    else printf("%d %s\n",dp[1][0],f[1][0]?"Yes":"No");}void dfs(int u){    if(!G[u].size())    {        dp[u][0]=0;        dp[u][1]=1;        return ;    }    for(int i=0; i<G[u].size(); i++)    {        int son=G[u][i];        dfs(son);        dp[u][1]+=dp[son][0];//选父亲一定不选儿子        if(!f[son][0]) f[u][1]=false;//如果不选儿子有多种方案,相当于选父亲也是多种方案        if(dp[son][0]>dp[son][1])//1        {            dp[u][0]+=dp[son][0];            if(!f[son][0]) f[u][0]=false;        }        else if(dp[son][0]==dp[son][1])//2        {            dp[u][0]+=dp[son][0];            f[u][0]=false;        }        else//3        {            dp[u][0]+=dp[son][1];            if(!f[son][1]) f[u][0]=false;        }        //1,2,3三种情况都是不选父亲,既然不选父亲,儿子选不选都行,所以加上最优情况        //然后在处理是否唯一时,如果儿子的最优是不唯一的,那么不选父亲也是不唯一的    }    ++dp[u][1];//当前的父亲选的时候加上自己}int main(){    while(scanf("%d",&n) && n)    {        inition();        input();        dfs(1);//这个代码的DFS和一般的DP形式不同,下面有代码        output();    }    return 0;}


void dfs(int root){    for(int i=0;i<maps[root].size();i++)        dfs(maps[root][i]);    for(int i=0;i<maps[root].size();i++)    {        int t=maps[root][i];//儿子        dp[root][0]+=max(dp[t][0],dp[t][1]);//不选父亲时找出选不选儿子的最优        if(dp[t][0]==dp[t][1])            vis[root][0]++;        else if(dp[t][0]>dp[t][1])            vis[root][0]+=vis[t][0];        else            vis[root][0]+=vis[t][1];        dp[root][1]+=dp[t][0];//选父亲加上不选儿子        vis[root][1]+=vis[t][0];    }    return;}

树形DP加上判断方案是否唯一 


原创粉丝点击