Uva 1220,Hali-Bula 的晚会

题目链接:https://uva.onlinejudge.org/external/12/1220.pdf

题意: 公司n个人,形成一个数状结构,选出最大独立集,并且看是否是唯一解。

分析:

d(i) 是 节点 i 的最优值, i 只有两种决策,就是选和不选。 转移方程:

d(i) = max {1+Σ1d(j),Σ2d(j)}; Σ1是所有孙子节点,Σ2是所有儿子节点。

那么状态的定义d(i,0),节点 i 不选,d(i,1),节点 i 选。

那么状态转移方程就是:

是否唯一 f(v,0) = 1 表示唯一, f(v,1) = 0 不唯一。

d(u,1) = sum{d(v,0)}(v是u的子节点),当所有 f(v,0) = 1,d(u,1) = 1;

d(u,0) = sum{max(d(v,0),d(v,1))}, if (d(v,0)==d(v,1)) f(u,0) = 0,取的对应的f()==0,f(u,0) = 0;

存树形结构,一个较好的方式用邻接表,每个字符串对应一个ID,可以用mapdict,有一个较好的函数,dict.count(s),s字符串出现的次数。

#include 
using namespace std;const int maxn = 200+5;
int cnt;
int n;
vector<int> sons[maxn];
int d[maxn][2],f[maxn][2];map<string,int> dict;int ID(const string &s) {if(!dict.count(s)) dict[s] = cnt++;return dict[s];
}int dp(int u,int k) {f[u][k] = 1;d[u][k] = k;for(int i=0;i) {int v = sons[u][i];if(k==1) {d[u][1] +=dp(v,0);if(!f[v][0]) f[u][1] = 0;}else {d[u][0] +=max(dp(v,0),dp(v,1));if(d[v][0]==d[v][1]) f[u][k] = 0;else if(d[v][0]>d[v][1]&&!f[v][0]) f[u][k] = 0;else if(d[v][1]>d[v][0]&&!f[v][1]) f[u][k] = 0;}}return d[u][k];
}int main()
{string s,s2;while(cin>>n>>s) {cnt = 0;dict.clear();for(int i=0;i)sons[i].clear();ID(s);for(int i=0;i1;i++) {cin>>s>>s2;sons[ID(s2)].push_back(ID(s));}printf("%d ",max(dp(0,0),dp(0,1)));bool unique = false;if(d[0][0]>d[0][1]&&f[0][0]) unique = true;if(d[0][1]>d[0][0]&&f[1][0]) unique = true;if(unique) printf("Yes\n");else printf("No\n");}return 0;
}
View Code

 

转载于:https://www.cnblogs.com/TreeDream/p/6002006.html


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部