Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2564 | Accepted: 859 |
Description
Input
Output
Sample Input
7 1 2 1 3 3 5 3 4 5 6 5 7
Sample Output
2
Source
#include <stdio.h> #include <stdlib.h> #include <string.h> #define INF 100 #define MAXN 110 #define MAXE 220 struct LEdge{ int ed, next; }edge[MAXE]; int head[MAXN], nEdge; void init(){ nEdge = 0; memset(head, 0xff, sizeof(head)); } void addEdge(int i, int j){ edge[nEdge].ed = j; edge[nEdge].next = head[i]; head[i] = nEdge++; } int f[MAXN][3]; int imin(int a, int b){ if (a < 0) return b; if (b < 0) return a; return a < b ? a : b; } int dfs(int pre, int cur){ int i, j, k, p, q, sum; sum = 0; for (i = head[cur]; i != -1; i = edge[i].next){ k = edge[i].ed; if (k == pre) continue; if (!dfs(cur, k)) return 0; sum += f[k][0]; } f[cur][0] = f[cur][1] = f[cur][2] = INF; f[cur][1] = sum; for (i = head[cur]; i != -1; i = edge[i].next){ p = edge[i].ed; if (p == pre) continue; f[cur][0] = imin(f[cur][0], f[p][2] - f[p][0] + sum + 1); f[cur][2] = imin(f[cur][2], f[p][2] - f[p][0] + sum); f[cur][2] = imin(f[cur][2], f[p][1] - f[p][0] + sum); for (j = edge[i].next; j != -1; j = edge[j].next){ q = edge[j].ed; if (q == pre) continue; f[cur][0] = imin(f[cur][0], f[p][1] - f[p][0] + f[q][1] - f[q][0] + sum + 1); f[cur][0] = imin(f[cur][0], f[p][2] - f[p][0] + f[q][1] - f[q][0] + sum + 1); f[cur][0] = imin(f[cur][0], f[p][1] - f[p][0] + f[q][2] - f[q][0] + sum + 1); f[cur][0] = imin(f[cur][0], f[p][2] - f[p][0] + f[q][2] - f[q][0] + sum + 1); } } // printf("cur = %d, f[0] = %d, f[1] = %d, f[2] = %d, t = %d, p = %d, q = %d, r = %d\n", cur, f[cur][0], f[cur][1], f[cur][2], t, p, q, r); if (f[cur][0] >= INF && f[cur][1] >= INF && f[cur][2] >= INF) return 0; return 1; } int main(){ int i, j, k, n; while(scanf("%d", &n) != EOF){ init(); for (k = 1; k < n; k++){ scanf("%d%d", &i, &j); addEdge(i, j); addEdge(j, i); } if (!dfs(0, 1) || f[1][0] >= INF) f[1][0] = -1; printf("%d\n", f[1][0]); } return 0; } /* f[i][0] i及其以下已成环 f[i][1] 仅i没成环 f[i][2] i带着一个长至少为2的链 f[i][0] = min( f[p][1] + f[q][1] + sum(f[其他][0]) + 1, f[p][2] + f[q][1] + sum(f[其他][0]) + 1, f[p][1] + f[q][2] + sum(f[其他][0]) + 1, f[p][2] + f[q][2] + sum(f[其他][0]) + 1, f[p][2] + sum(f[其他][0]) + 1) f[i][1] = sum(f[其他][0]) f[i][2] = min( f[p][2] + sum(f[其他][0]), f[p][1] + sum(f[其他][0])) 开始无效值是-1,虽然做了好多好多特判 例如,有的子树本身无法全部成环,这样的点如果有一个, 可以通过和当前点组成环,或者和其他链组成环,或者作为当前点的链 如果有两个,则必须把他俩连一块 如果多于两个,说明无解 但是都WA掉了 后来看了网上的,没那么多特判,枚举起来也特暴力 初值设的INF,于是改成比较暴力的二重循环,而不是一重去找, 写的简单了,也就过了 经验: 尽量简洁,卡住了就释放些暴力 */