这个题 还是很简单的、 最主要的还是通过各种方法, 把一个 无根树 变成有根树。然后进行搜索。
这个建树的过程很重要。 用的是 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;
}