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 and vi'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
题意:给定一棵树,不同颜色用不同数字表示,相邻结点不能染相同颜色,问正确染完色后,整棵树的颜色加起来最小值是多少。
思路:树形DP,dp[u][i]代表结点u染颜色i的时候最小情况。然后就是常规的树形DP了。。
代码:
#include <stdio.h>
#include <string.h>
#include <vector>
#define INF 0x3f3f3f3f
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N = 10005;
int n, dp[N][10];
char str[25555];
vector<int> g[N];
void handle() {
int i = 0;
int len = strlen(str), num = -1;
while (str[i] < '0' || str[i] > '9') i++;
for (;str[i] != ':'; i++) {
if (num == -1)
num = str[i] - '0';
else
num = num * 10 + str[i] - '0';
}
int u = num;
num = -1;
for (;i <= len; i++) {
if (num != -1 && (str[i] < '0' || str[i] > '9')) {
g[u].push_back(num);
g[num].push_back(u);
num = -1;
}
else if (str[i] >= '0' && str[i] <= '9') {
if (num == -1)
num = str[i] - '0';
else
num = num * 10 + str[i] - '0';
}
}
}
void dfs(int u, int fa) {
int i;
for (i = 1; i <= 6; i++)
dp[u][i] = i;
for (i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (v == fa) continue;
dfs(v, u);
for (int i = 1; i <= 6; i++) {
int tmp = INF;
for (int j = 1; j <= 6; j++) {
if (i == j) continue;
tmp = min(tmp, dp[v][j]);
}
dp[u][i] += tmp;
}
}
}
int main() {
while (~scanf("%d%*c", &n) && n) {
memset(g, 0, sizeof(g));
while (gets(str) && str[0] != '\0') {
handle();
}
dfs(0, -1);
int ans = INF;
for (int i = 1; i <= 6; i++)
ans = min(ans, dp[0][i]);
printf("%d\n", ans);
}
return 0;
}