uva1220树的最大独立集
题意:公司里除了老板,每个人都有一个直属上司,要求选尽量多的人,但不能同时选一个人和他的直属上司,问最多能选多少个人,以及在人数最多的情况下方案是否唯一。
思路:d[u][0]表示不选u点能得到的最大人数d[u][0]=sum{max(d[v][0],d[v][1])}
d[u][1]表示选u点能得到的最大人数d[u][1]=sum{d[v][0]}
f[u][0]表示不选u点能获得的最大人数方案是否唯一,1.d[v][0]=d[v][1],不唯一(用1表示不唯一)。2.选择d[v][0]且f[v][0]=1;选择d[v][1]且f[v][1]=1。
f[u][1]表示选择u点能获得的最大人数方案是否唯一,f[v][0]=1时f[u][1]=1。
dfs
#include<bits/stdc++.h> using namespace std; int d[204][2],f[205][2]; vector<int>child[205]; void dp(int u) { if(child[u].size()==0) { d[u][1]=1; d[u][0]=0; return; } int len=child[u].size(); for(int i=0;i<len;i++) { int a=child[u][i]; dp(a); if(d[a][0]>d[a][1]){d[u][0]=d[u][0]+d[a][0];if(f[a][0]==1)f[u][0]=1;} if(d[a][1]==d[a][0]){d[u][0]=d[u][0]+d[a][0];f[u][0]=1;}//²»Î¨Ò» if(d[a][0]<d[a][1]){d[u][0]=d[u][0]+d[a][1];if(f[a][1]==1)f[u][0]=1;} d[u][1]=d[u][1]+d[a][0]; if(f[a][0]==1)f[u][1]=1; } d[u][1]++; } int main() { int n; cin>>n; while(n) { memset(f,0,sizeof(f)); memset(d,0,sizeof(d)); memset(child,0,sizeof(child)); map<string,int>v; string s1,s2; cin>>s1; int num=1; v[s1]=num++; for(int i=0;i<n-1;i++) { cin>>s1>>s2; if(!v[s1])v[s1]=num++; if(!v[s2])v[s2]=num++;//±àºÅ child[v[s2]].push_back(v[s1]); } dp(1); int flag=0; if(d[1][1]>d[1][0])flag=1; cout<<d[1][flag]<<' '; if(f[1][flag]==1||d[1][0]==d[1][1])cout<<"No"<<endl; else cout<<"Yes"<<endl; cin>>n; } return 0; }