这道题几乎就是树的最大独立集问题,只不过要判断唯一性。
在这里用了个ju[0], ju[1],ju[2],来判断相应的d, s, gs数组中值得唯一性.
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <cmath>
using namespace std;
#define maxn 200 + 5
map<string, int> m;
vector<int> v[maxn];
int d[maxn], s[maxn], gs[maxn], ju[3][maxn];
void dp(int n, int fa)
{
if(v[n].empty())
{
d[n] = 1;
return ;
}
for(int i = 0; i < v[n].size(); i++)
{
int h = v[n][i];
dp(h, n);
s[n] += d[h];
if(ju[0][h])
ju[1][n] = true;
if(fa != -1)
{
gs[fa] += d[h];
if(ju[0][h])
ju[2][fa] = true;
}
}
if(s[n] == gs[n] + 1)
{
d[n] = s[n];
ju[0][n] = true;
}
else if(s[n] > gs[n] + 1)
{
d[n] = s[n];
if(ju[1][n])
ju[0][n] = true;
}
else {
d[n] = gs[n] + 1;
if(ju[2][n])
ju[0][n] = true;
}
}
int main()
{
// freopen("in.txt", "r", stdin);
int n;
while(cin >> n && n)
{
string s1, s2;
int cnt = 0;
m.clear();
for(int i = 0; i <= maxn; i++)
v[i].clear();
cin >> s1;
m[s1] = cnt++;
for(int i = 1; i < n; i++)
{
cin >> s1 >> s2;
if(!m.count(s1))
m[s1] = cnt++;
if(!m.count(s2))
m[s2] = cnt++;
v[m[s2]].push_back(m[s1]);
}
memset(s, 0, sizeof(s));
memset(gs, 0, sizeof(gs));
memset(ju, 0, sizeof(ju));
dp(0, -1);
cout << d[0] << " ";
if(ju[0][0])
cout << "No" << endl;
else
cout << "Yes" << endl;
}
return 0;
}