Problem A
ALTERNATIVE ARBORECSENCE
Given a graph, we define "proper coloring" as coloring of the graph nodes in such way that no two adjacent nodes have the same color. If we map each color to a positive integer, we can calculate the sum of all colors assigned to the graph.
In this problem you will be given a tree (connected graph with no simple loops). Can you determine what the minimum color sum can be achieved when the tree is properly colored? (Image to the right shows a proper coloring of the second example tree with sum=11)
Input
The input file consists of several test cases. Each test case starts with n (1 ≤ n ≤ 10000), the number of nodes in the tree. Next n lines will be of the form "u: v1 v2 ... vk" where u is the root of a subtree andvi's are its children (0 ≤ u, vi ≤ n-1).
Every test case will be followed by a blank line. Input ends with a case n=0, which should not be processed.
Output
For each test case print the minimum sum of colors that can be achieved by some proper coloring of the tree.
Sample Input
2 0: 1: 0 8 0: 1 2 3 1: 4 5 2: 3: 6 7 4: 5: 6: 7: 0
Output for the Sample Input
3 11
Darko Aleksic, October 2007
贪心是不对的,可以简单想一下。因为是树,所以总的颜色不会很多,20足够了。输入比较恶心,直接套了别人的代码。dp[i][j]表示第i个点用颜色j时,它及其儿子涂完色的最小值。最后,注意是无根树!所以任选一个点作为根,再dfs。
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <stack>
#include <set>
#include <cstring>
#include <stdlib.h>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100000 + 5;
const int maxc = 20;
const int INF = 1000000000;
vector<int> G[maxn];
int n;
bool get () {
char s[maxn*6];
gets(s);
if (s[0] == '\0') return false;
int len = strlen(s), i = 0;
int u = -1, v = -1;
while (s[i] < '0' && s[i] > '9') i++;
for (; s[i] != ':'; i++) {
if (u == -1) u = s[i] - '0';
else u = u * 10 + s[i] - '0';
}
for (; i <= len; i++) {
if (s[i] >= '0' && s[i] <= '9') {
if (v == -1) v = s[i] - '0';
else v = v * 10 + s[i] - '0';
} else {
if (v != -1) {
G[u].push_back(v);
G[v].push_back(u);
v = -1;
}
}
}
return true;
}
int dp[maxn][maxc];
int dfs(int x, int k, int fa){
if(dp[x][k] != INF) return dp[x][k];
int ret = k;
for(int i = 0;i < G[x].size();i++){
int Min = INF;
int to = G[x][i];
if(to == fa) continue;
for(int j = 1;j < maxc;j++){
if(j == k) continue;
Min = min(Min, dfs(to, j, x));
}
ret += Min;
}
return dp[x][k] = ret;
}
int main(){
while(scanf("%d", &n)){
if(n == 0) break;
for(int i = 0;i < n;i++)
G[i].clear();
getchar();
while(get());
for(int i = 0;i < n;i++){
for(int j = 0;j < maxc;j++){
dp[i][j] = INF;
}
}
int ans = INF;
for(int i = 1;i < maxc;i++){
ans = min(ans, dfs(0, i, -1));
}
printf("%d\n", ans);
}
return 0;
}