UVa 1220 Party at Hai-Bula(树形DP)

来源:互联网 发布:python编写远程控制 编辑:程序博客网 时间:2024/06/06 18:28

题目链接:http://arena.acmclub.com/problem.php?id=15595

import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Scanner;public class Main {static int max = 200 + 10;static int[][] d = new int[max][2];// d[i][0]表示不选,d[i][1]表示选。// f[i][0]==1表示不选,且方案唯一,f[i][0]==0表示选、且方案不唯一。// f[i][1]==1表示选,且方案唯一,f[i][1]==0表示选、且方案不唯一。static int[][] f = new int[max][2];static ArrayList<Integer>[] sons = new ArrayList[max];static Map<String, Integer> dict;static int n;static int cnt;public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNextInt()) {n = in.nextInt();if (n == 0)break;cnt = 0;dict = new HashMap<String, Integer>();for (int i = 0; i < n; i++) {sons[i] = new ArrayList<Integer>();}String s = in.next();ID(s);for (int i = 0; i < n - 1; i++) {String s1 = in.next();// 下属String s2 = in.next();// 上司sons[ID(s2)].add(ID(s1));}int max0 = dp(0, 0);int max1 = dp(0, 1);System.out.print(Math.max(max0, max1) + " ");boolean unique = false;if (max1 > max0 && f[0][1] == 1)unique = true;if (max0 > max1 && f[0][0] == 1)//注意这里不是else if。unique = true;if (unique)System.out.println("Yes");elseSystem.out.println("No");}}public static int ID(String s) {//这里运用与uva12186类似的方法if (dict.get(s) == null)//将上司(编号)的下属(编号)添加到上司所在的容器中。dict.put(s, cnt++);return dict.get(s);}public static int dp(int u, int k) {f[u][k] = 1;// 先默认设置为1,然后在后面的判断中,不满足条件,再改为0d[u][k] = k;// 选中为0,不选中为1,而0和1都是k值,故d[u][k] = k;for (int i = 0; i < sons[u].size(); i++) {int v = sons[u].get(i);// 上司u的下属v。if (k == 1) {d[u][1] += dp(v, 0);if (f[v][0] == 0)f[u][1] = 0;} else {int max0 = dp(v, 0);int max1 = dp(v, 1);d[u][0] += Math.max(max0, max1);if (max0 > max1 && f[v][0] == 0)f[u][0] = 0;else if (max1 > max0 && f[v][1] == 0)f[u][0] = 0;else if (max0 == max1)f[u][0] = 0;}}return d[u][k];}}


题意:

    一个公司员工要举行聚会,公司里有n(n<=200)个人形成一个树状结构。要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一

分析:

    本题几乎就是树的最大独立集问题,不过多了一个要求:判断唯一性。设:

1,d(u,0)和f(u,0)表示以u为根的子树中,不选uhko 能得到的最大人数以及方案唯一性。(f(u,0)=1表示唯一,0表示不唯一)

2,d(u,1)和f(u,1)表示以u为根的子树中,选u点能得到的最大人数以及方案的唯一性。

相应地,状态转移方程也有两套。

1,d(u,1)的计算:因为选了u,所以u的子结点都不能选,因此d(u,1)=sum{d(v,0) | v是u的子结点}。当且仅当所有f(v,0)=1时,f(u,1)才是1。

2,d(u,0)的计算:因为u没有选,所以每个子结点v可选可不选,即d(u,0) = sum{max (d(v,0),d(v,1))}。什么情况下方案是唯一的呢?首先,如果某个d(v,0)和d(v,1)相等,则不唯一;其次,如果max取到的那个值对应的f=0,方案也不唯一(如d(v,0)>d(v,1) && f(v,0)==0,则f(u,0)=0;这里可以细分为两种情况)。

0 0
原创粉丝点击