UVA 1220 Party at Hali-Bula

本文介绍了一种将无根树转换为有根树的方法,并通过动态规划解决特定问题。利用map和vector实现树的构建过程,最终通过递归函数完成遍历并计算最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个题 还是很简单的、  最主要的还是通过各种方法, 把一个 无根树 变成有根树。然后进行搜索。


这个建树的过程很重要。 用的是 map 标记 和  vector 的下标。


然后再来  实现就简单了。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
using namespace std;
#define ll long long
#define maxn 200+10
#define INF 1<<30
map <string , int> q;
vector <string> fa;
vector <int> son[maxn];
int f[maxn][3] = {0};
int init(){
    q.clear();
    fa.clear();
    for(int i = 0; i < maxn; i++)
        son[i].clear();
    memset(f,0,sizeof(f));
}
int get_id(string  &s){
    if(q.count(s))
        return q[s];
    fa.push_back(s);
    return q[s] = fa.size() - 1;
}
int dp(int i,int j){
    if(son[i].empty()){
        f[i][j] = 1;
        if(j == 0)
            return 0;
        return 1;
    }
    int v = 0;
    if(j == 0){
        int len = son[i].size();
        int ok = 1;
        for(int k = 0; k < len; k++){
            int no_cho = dp(son[i][k] , 0),cho = dp(son[i][k] , 1);
            v += max(no_cho , cho);
            if(no_cho > cho ){
                if(f[son[i][k]][0] != 1) ok = 0;
            }
            else if(no_cho < cho)
                if(f[son[i][k]][1] != 1) ok=0;
            else ok=0;
        }
        f[i][j]=(ok ? 1 : 0);
    }
    else{
        v = 1;
        int len = son[i].size(), ok = 1;
        for(int k = 0; k < len; k++){
            v += dp(son[i][k] , 0);
            if(f[son[i][k]][0] != 1) ok=0;
        }
        f[i][j]=(ok ? 1 : 0);
    }
    return v;
}
int main (){
    int n;
    while(scanf("%d",&n) && n){
        init();
        string s;
        cin >> s;
        get_id(s); // 分配地址
        for(int i = 1; i < n; i++){
            string s1,s2;
            cin >> s1 >> s2;
            son[get_id(s2)].push_back(get_id(s1));
        }
        int no_cho = dp(0,0), cho = dp(0,1);
        int flag = 1;//唯一
        int max_;
        if(no_cho == cho){
            flag = 0;
            max_ =cho;
        }
        else if(no_cho > cho){
            if(f[0][0] != 1)
                flag = 0;
            max_ = no_cho;
        }
        else {
            if(f[0][1] != 1)
                flag = 0;
            max_ = cho;
        }
        cout << max_ << (flag ? " Yes" : " No") << endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值