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"); } }