UVA 1220 Party at Hali-Bula (樹形DP)

weixin_30488085發表於2020-04-06

求一棵數的最大獨立集結點個數並判斷方案是否唯一。

dp[i][j]表示以i為根的子樹的最大獨立集,j的取值為選和不選。

決策:

當選擇i時,就不能選擇它的子結點。

當不選i時,它的子結點可選可不選。

判斷唯一性:當選擇的某個子節點方案不唯一,父節點的方案就不唯一,或者某個子節點選或不選方案數一樣。

轉移順序:按照拓撲序轉移或dfs都可以。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 201;
const int pick = 1;
const int drop = 0;

int d[maxn][2];
bool f[maxn][2];// NotUnique?
int fa[maxn];
int deg[maxn];
int n;

void topo()
{
    queue<int> q;
    for(int i = 0; i < n; i++){
        d[i][pick] = 1;
        d[i][drop] = 0;
        f[i][pick] = f[i][drop] = 0;
        if(deg[i] == 0){
            q.push(i);
        }
    }

    while(q.size()){
        int u = q.front(); q.pop();
        int p = fa[u];
        int &a = d[u][drop], &b = d[u][pick];
        d[p][pick] += a;
        f[p][pick] |= f[u][drop];
        if(a>b){
            d[p][drop] += a;
            f[p][drop] |= f[u][drop];
        }else {
            d[p][drop] += b;
            f[p][drop] |= a == b || f[u][pick];
        }
        deg[p]--;
        if(deg[p] == 0) {
            q.push(p);
        }
    }
}

#define MP make_pair
#define PB push_back
#define fi first
#define se second
map<string,int> idx;
int idx_cnt;
int ID(string &x)
{
    map<string,int>::iterator it = idx.find(x);
    if(it != idx.end()) return it->se;
    idx.insert(MP(x,idx_cnt));
    return idx_cnt++;
}

string name;
const int root = 0;
bool read()
{
    scanf("%d",&n);
    if(n == 0) return false;
    idx.clear();
    cin>>name;
    idx.insert(MP(name,root));

    idx_cnt = 1;
    fill(deg,deg+n,0);
    for(int i = 1; i < n; i++){
        cin>>name;
        int v = ID(name);
        cin>>name;
        int p = ID(name);
        fa[v] = p;
        deg[p]++;
    }
    return true;
}

int main()
{
    //freopen("in.txt","r",stdin);
    fa[root] = -1;
    while(read()){
        topo();
        int k = d[root][pick]>d[root][drop]?pick:drop;
        bool flag = d[root][k] != d[root][k^1] && !f[root][k];
        printf("%d ",d[root][k]);
        if(flag) puts("Yes");
        else puts("No");
    }
    return 0;
}

 

轉載於:https://www.cnblogs.com/jerryRey/p/4743829.html

相關文章