poj3342

/***************************************************************\
 *Author:Hu Wenbiao
 *Created Time: Tue 17 Aug 2010 09:36:56 AM CST
 *File Name: main.cpp
 *Description:树状dp.用map处理字符串得到编号,再tree_dp
\***************************************************************/
//*========================*Head File*========================*\\

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<map>
#include<string.h>
/*----------------------*Global Variable*----------------------*/
int first[210], n, tot, cnt, boss, employee;
int dp[210][2];
char a[110], b[110];
bool flag, visited[210], isroot[210];
struct Edge {
    int next, to;
} edge[210];
#define insert(a,b) bcm.insert(pair<string,int>(a,b));
//*=======================*Main Program*=======================*//
using namespace std;

void insertedge(int a, int b)
{
    edge[tot].to = b;
    edge[tot].next = first[a];
    first[a] = tot++;
    isroot[b] = false;
}

void tree_dp(int from)
{
    visited[from] = true;
    int p = first[from], to;
    dp[from][1] = 1;
    while (p != -1) {
	to = edge[p].to;
	p = edge[p].next;
	tree_dp(to);
	dp[from][0] += max(dp[to][0], dp[to][1]);
	dp[from][1] += dp[to][0];
    }
}

bool check(int from, bool cho)
{				//cho表示from是否被选中
    visited[from] = true;
    int p = first[from], to;
    if (cho) {			//from被选
	while (p != -1) {
	    to = edge[p].to;
	    p = edge[p].next;
	    if (!check(to, 0))	//子结点不能被选,检查各个子结点不被选的情况
		return false;
	}
    } else {			//from未被选
	while (p != -1) {
	    to = edge[p].to;
	    p = edge[p].next;
	    if (dp[to][0] == dp[to][1])	//子结点可选可不选,一旦两者相等,结果不唯一
		return false;
	    if (dp[to][0] > dp[to][1]) {	//这时子结点不被选
		if (!check(to, 0))
		    return false;
	    } else {		//了结点被选
		if (!check(to, 1))
		    return false;
	    }
	}
    }
    return true;
}

int main()
{
    map < string, int >bcm;	//存放姓名和编号
    map < string, int >::iterator iter;
    while (scanf("%d", &n) != EOF && n) {
	memset(first, -1, sizeof(first));
	memset(dp, 0, sizeof(dp));
	memset(isroot, true, sizeof(isroot));
	memset(visited, false, sizeof(visited));
	bcm.clear();
	tot = 0;
	cnt = 0;
	flag = true;
	scanf("%s", a);		//bigboss
	insert(a, ++cnt);	//cnt是编号,从1开始
	for (int i = 1; i < n; i++) {
	    scanf("%s %s", a, b);
	    iter = bcm.find(a);
	    if (iter == bcm.end()) {	//a之前未出现
		insert(a, ++cnt);
		employee = cnt;
	    } else {
		employee = iter->second;
	    }
	    iter = bcm.find(b);
	    if (iter == bcm.end()) {
		insert(b, ++cnt);
		boss = cnt;
	    } else {
		boss = iter->second;
	    }
	    insertedge(boss, employee);	//将边加入树中
	}
	tree_dp(1);
	int ans = max(dp[1][0], dp[1][1]);
	printf("%d ", ans);
	memset(visited, 0, sizeof(visited));
	if (dp[1][0] == dp[1][1])
	    flag = false;
	else if (dp[1][0] > dp[1][1])
	    flag = check(1, 0);
	else
	    flag = check(1, 1);
	if (flag)
	    printf("Yes\n");
	else
	    printf("No\n");
    }
}

posted @ 2010-08-17 14:19  open source  阅读(336)  评论(0编辑  收藏  举报