您的位置:首页 > 其它

UVa 1220 - Party at Hali-Bula(最大独立集)

2015-07-26 16:23 405 查看
d[u][1]d[u][1]和d[u][0]d[u][0]分别表示选结点u和不选结点u在它的子树中最大的数目,f[u][t]f[u][t]表示相应选法的唯一性。

d[u][1]=sum{d[v][0]}d[u][1]=sum\{d[v][0]\},d[u][0]=sum{max(d[v][0],d[v][1])}d[u][0]=sum\{max(d[v][0],d[v][1])\}。

当选择结点的子树的方案有不唯一时,该结点方案不唯一。

#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
using namespace std;
const int maxn=210;
map<string,int> id;
int d[maxn][2];
bool f[maxn][2];
vector<int> sons[maxn];
int dp(int u,int t){
int& k=d[u][t]=t;
if(sons[u].empty()) return k;
if(t==1){
for(int i=0;i<(int)sons[u].size();++i){
k+=dp(sons[u][i],0);
if(f[sons[u][i]][0]!=1)
f[u][1]=false;
}
}
else {
for(int i=0;i<(int)sons[u].size();++i){
int s=sons[u][i],a=dp(s,0),b=dp(s,1);
k+=max(a,b);
if(a==b||(a>b&&!f[s][0])||(a<b&&!f[s][1]))
f[u][0]=false;
}
}
return k;
}
int main(){
int n;
while(cin>>n&&n){
id.clear();
memset(d,0,sizeof(d));
memset(f,1,sizeof(f));
for(int i=0;i<maxn;++i) sons[i].clear();
string s;cin>>s;
int cnt=0;
id[s]=cnt++;
for(int i=2;i<=n;++i){
cin>>s;
if(!id.count(s)) id[s]=cnt++;
int k=id[s];
cin>>s;
if(!id.count(s)) id[s]=cnt++;
sons[id[s]].push_back(k);
}
int a=dp(0,0),b=dp(0,1);
bool unk=true;
if(a==b||(a>b&&!f[0][0])||(a<b&&!f[0][1])) unk=false;
printf("%d %s\n",max(a,b),unk?"Yes":"No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: