• Party at Hali-Bula (树形DP+判断方案是否唯一)


    思路

    求人数的部分为经典题
    重点是判断方案是否唯一:
    (vis[u][j])表示以(u)为根并且(u)的状态为(j)时方案是否唯一
    转移就是如果子节点有方案不唯一的话,父节点的方案也不唯一

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll, ll>PLL;
    typedef pair<int, int>PII;
    typedef pair<double, double>PDD;
    #define I_int ll
    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;
    }
    #define read read()
    #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
    #define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i<(b);i++)
    #define per(i,a,b) for(int i=(a);i>=(b);i--)
    #define perr(i,a,b) for(int i=(a);i>(b);i--)
    ll ksm(ll a, ll b, ll p)
    {
        ll res = 1;
        while(b)
        {
            if(b & 1)res = res * a % p;
            a = a * a % p;
            b >>= 1;
        }
        return res;
    }
    const int inf = 0x3f3f3f3f;
    #define PI acos(-1)
    const double eps = 1e-8;
    const int maxn =510;
    map<string,int>mp;
    vector<int>g[maxn];
    int dp[maxn][2],vis[maxn][2],st[maxn];
    void dfs(int u){
        dp[u][1]=1;
        dp[u][0]=0;
        st[u]=1;
        for(int i=0;i<g[u].size();i++){
            int j=g[u][i];
            if(st[j]) continue;
            dfs(j);
            
            dp[u][1]+=dp[j][0];
            if(vis[j][0]) vis[u][1]=1;
            
            if(dp[j][0]>dp[j][1]){
                dp[u][0]+=dp[j][0];
                if(vis[j][0]) vis[u][0]=1;
            }
            else{
                dp[u][0]+=dp[j][1];
                if(vis[j][1]||dp[j][0]==dp[j][1]) vis[u][0]=1;
            }
        }
    }
    void solve(){
        int n;
        while(~scanf("%d",&n)){
            if(!n) break;
            mp.clear();
            memset(dp,0,sizeof dp);
            memset(st,0,sizeof st);
            memset(vis,0,sizeof vis);
            string s;cin>>s;
            mp[s]=1;
            int idx=2;
            for(int i=1;i<n;i++){
                string x,y;cin>>x>>y;
                int xx,yy;
                if(!mp[x]) mp[x]=idx++;
                if(!mp[y]) mp[y]=idx++;
                xx=mp[x],yy=mp[y];
                g[yy].push_back(xx);
            }
            dfs(1);
            cout<<max(dp[1][0],dp[1][1])<<" ";
            if(dp[1][0]==dp[1][1]) puts("No");
            else{
                if(dp[1][0]>dp[1][1]){
                    if(vis[1][0]) puts("No");
                    else puts("Yes");
                }
                else if(dp[1][1]>dp[1][0]) {
                    if(vis[1][1]) puts("No");
                    else puts("Yes");
                }
            }
            for(int i=1;i<=idx;i++) g[i].clear();
        }
    }
    
    int main() {
    	int T=1;
    	while(T--){
    		solve();
    	}
    	return 0;
    }
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    认识ASP.NET 中的 AppDomain
    试验总结1 改变递归函数中的执行内容
    试验总结2 break与continue
    开篇的话
    01复杂度3 二分查找
    02线性结构2 一元多项式的乘法与加法运算
    01复杂度2 Maximum Subsequence Sum
    02线性结构4 Pop Sequence
    01复杂度1 最大子列和问题
    02线性结构1 两个有序链表序列的合并
  • 原文地址:https://www.cnblogs.com/OvOq/p/14794733.html
Copyright © 2020-2023  润新知