UVA 1220 题解

2017/10/23 OI 树形DP

UVA 1220 题解

题目

链接

UVA 1220

题面

自己看链接

题意

  一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一

题解

思路

  水的树形DP入门题。代码满烦的,要记录两种状态的变化:一个是人数的变化,一个是方案是否唯一。且两种方案都有两个子状态:是否取了当前的节点

代码

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>

using namespace std;

map<string, int> names;
int str_count = 0;
int get_id(string str)
{
	if (!names.count(str))
		names[str] = str_count++;
	return names[str];
}

vector<vector<int> > data;
vector<vector<int> > f;
vector<vector<bool> > flag;
int n;
void compute(int index)
{
	if (f[index][0] || f[index][1])
		return;
	else
	{
		if (data[index].empty())
		{
			f[index][1] = 1;
			f[index][0] = 0;
			flag[index][1] = true;
			flag[index][0] = true;
			return;
		}
		flag[index][0] = true;
		flag[index][1] = true;
		f[index][1] = 1;
		for (int i = 0; i < data[index].size(); i++)
		{
			compute(data[index][i]);
			f[index][0] += max(f[data[index][i]][0], f[data[index][i]][1]);
			f[index][1] += f[data[index][i]][0];
			if (f[data[index][i]][1] == f[data[index][i]][0] ||
				(f[data[index][i]][0] > f[data[index][i]][1] && !flag[data[index][i]][0]) ||
				(f[data[index][i]][0] < f[data[index][i]][1] && !flag[data[index][i]][1]))
				flag[index][0] = false;
			if (flag[data[index][i]][0] == false)
				flag[index][1] = false;
		}
	}
}

int main()
{
	while (cin >> n && n)
	{
		names.clear();
		str_count = 0;
		data.clear();
		f.clear();
		flag.clear();
		data.resize(n, vector<int>());
		for (int i = 0; i < n; i++)
		{
			string buf1, buf2;
			if (i == 0)
			{
				cin >> buf1;
				get_id(buf1);
			}
			else
			{
				cin >> buf1 >> buf2;
				int to = get_id(buf1);
				int from = get_id(buf2);
				data[from].push_back(to);
			}
		}
		f.resize(n, vector<int>(2, 0));
		flag.resize(n, vector<bool>(2, true));
		compute(0);
		if (f[0][1] == f[0][0])
		{
			cout << f[0][1] << " No" << endl;
		}
		else if (f[0][1] > f[0][0])
		{
			cout << f[0][1] << " " << (flag[0][1] ? "Yes" : "No") << endl;
		}
		else
		{
			cout << f[0][0] << " " << (flag[0][0] ? "Yes" : "No") << endl;
		}
	}
	return 0;
}
Show Disqus Comments

Search

    welcome to visit my github

    creatorlxd's github

    Table of Contents