当前位置: 代码迷 >> 综合 >> UVA 1220 Party at Hali-Bula(树的最大独立集)
  详细解决方案

UVA 1220 Party at Hali-Bula(树的最大独立集)

热度:77   发布时间:2023-09-23 09:11:14.0

树的独立集:即集合中任选两个点互相不相邻,互相不构成父子关系。 且其中最大的集合即为最大独立集

状态定义:1)d(u,1) ,f(u,1) 表示选u点情况下,在u的子树中,能得到的最大人数以及方案的唯一性

                2)d(u,0) ,f(u,0) 表示不选u点情况下,在u的子树中,能得到的最大人数以及方案的唯一性

状态转移:对于1)在选了u的情况下,肯定就不能选u的字结点,所以只能选择子结点为根的子树即 d(v,0)

                              即d(u,1) = max{ d(v,0) } 且当所有f(v,0) 唯一,f(u,1)才唯一

                 对于2)可以选子结点,也可以不选,选其中大的 即 d(u,0) = max { d(v,0) ,d(v,1) } 其中如果d(v,0)大

                              且f(v,0)不唯一,那么d(v,0) 不唯一, 如果d(v,1)大且f(u,0)不唯一,那么f(u,0) 不唯一


#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm> 
#include<vector>
#include<map>
using namespace std;
const int maxn=200+5;
map<string,int> dict;
vector<int> sons[maxn];
int cnt,d[maxn][2];bool f[maxn][2];
int ID(string s)
{if(!dict.count(s)) dict[s]=cnt++;return dict[s];
}
int dp(int u,int k)
{d[u][k]=k;   //如果k==1 ,那么要加上u点 f[u][k]=true;for(int i=0;i<sons[u].size();i++){int v=sons[u][i];if(k){d[u][1]+=dp(v,0);if(!f[v][0]) f[u][1]=false;}	else {int x=dp(v,0),y=dp(v,1);if(x>y) {if(!f[v][0]) f[u][0]=false;d[u][0]+=x;}else if(x<y){if(!f[v][1]) f[u][0]=false;d[u][0]+=y;}else {f[u][0]=false;d[u][0]+=x;}}}return d[u][k];
}
int main()
{int n;string s,s1;while(scanf("%d",&n)==1&&n){cnt=0;for(int i=0;i<n;i++) sons[i].clear();dict.clear();cin>>s;ID(s);for(int i=0;i<n-1;i++){cin>>s>>s1;sons[ID(s1)].push_back(ID(s));}dp(0,0);dp(0,1);printf("%d ",max(d[0][0],d[0][1]));bool unique=true;if(d[0][0]>d[0][1]&&!f[0][0]) unique=false; if(d[0][1]>d[0][0]&&!f[0][1]) unique=false;if(d[0][0]==d[0][1]) unique=false;cout<<(unique?"Yes":"No")<<endl;}return 0;
} 



  相关解决方案