您的位置:首页 > 其它

UVa 1220:Party at Hali-Bula(DP)

2015-09-17 23:01 387 查看
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=847&page=show_problem&problem=3661

题意:公司里有n(n≤200)(n \le 200)个人形成一个树形结构,即除了老板之外每个员工都有唯一的直属上司。要求选尽量多的人,但不能同时选择一个人和他的直属上司。问:最多能选多少人,以及在人数最多的前提下方案是否唯一。(本段摘自《算法竞赛入门经典(第2版)》

分析:

树的最大独立集问题,再加一个状态来表示答案是否唯一即可。

代码:

#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <cctype>
#include <stack>
#include <set>
#include <map>

using namespace std;

const int maxn = 200 + 5, INF = 1e9;

int n, id;
string s1, s2;
map< string, int > m;
vector< int > sons[maxn];
int dp[maxn][maxn], f[maxn][maxn];

int DP(int u, int k)
{
if (dp[u][k] >= 0)
return dp[u][k];
dp[u][k] = k;
f[u][k] = 1;
for (int i = 0; i < sons[u].size(); ++i)
{
int v = sons[u][i];
if (k)
{
dp[u][1] += DP(v, 0);
if (!f[v][0])
f[u][1] = 0;
}
else
{
dp[u][0] += max(DP(v, 0), DP(v, 1));
if (dp[v][0] == dp[v][1])
f[u][0] = 0;
else if (dp[v][0] > dp[v][1] && !f[v][0])
f[u][0] = 0;
else if (dp[v][0] < dp[v][1] && !f[v][1])
f[u][0] = 0;
}
}
return dp[u][k];
}

int main()
{
while (~scanf("%d", &n), n)
{
memset(dp, -1, sizeof(dp));
memset(f, 0, sizeof(f));
for (int i = 0; i < n; ++i)
sons[i].clear();
m.clear();
id = 0;
cin >> s1;
m[s1] = id++;
for (int i = 0; i < n - 1; ++i)
{
cin >> s1 >> s2;
if (m.find(s1) == m.end())
m[s1] = id++;
if (m.find(s2) == m.end())
m[s2] = id++;
sons[m[s2]].push_back(m[s1]);
}
DP(0, 0);
DP(0, 1);
if (dp[0][0] == dp[0][1])
printf("%d No\n", dp[0][0]);
else if (dp[0][0] > dp[0][1])
printf("%d %s\n", dp[0][0], f[0][0] ? "Yes" : "No");
else
printf("%d %s\n", dp[0][1], f[0][1] ? "Yes" : "No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: