链接:http://poj.org/problem?id=3164
继续最小树形图~
这次的最小树形图直接套模板上去就可以了....我把刚才那篇的写法用上去,AC的还是相当顺利的,就只有刚开始打错了几个字,搞到TLE了一下。于是,我确定这种写法(我觉得已经是相当飘逸的了)可以加入我的模板...
题意就没必要解释了,这么明显。
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 6 typedef double ll; 7 8 const int maxn = 105; 9 const ll inf = 1e30; 10 int pre[maxn], fold[maxn], vis[maxn]; 11 ll cost[maxn], min_cost; 12 13 struct edge{ 14 int b; 15 int e; 16 ll c; 17 }E[maxn * maxn]; 18 19 struct point{ 20 ll x; 21 ll y; 22 }P[maxn]; 23 24 ll dis(point a, point b){ 25 ll dx = a.x - b.x; 26 ll dy = a.y - b.y; 27 28 return sqrt(dx * dx + dy * dy); 29 } 30 31 bool make_tree(int root, int v, int e){ 32 int i, j; 33 int s, t, cnt; 34 35 min_cost = 0; 36 while (true){ 37 for (i = 0; i < v; i++){ 38 cost[i] = 1e31; 39 } 40 for (i = 0; i < e; i++){ 41 s = E[i].b; 42 t = E[i].e; 43 #ifndef ONLINE_JUDGE 44 printf("%d %d: %.2f\n", s, t, E[i].c); 45 #endif 46 47 if (cost[t] > E[i].c && s != t){ 48 cost[t] = E[i].c; 49 pre[t] = s; 50 } 51 } 52 #ifndef ONLINE_JUDGE 53 for (i = 0; i < v; i++) 54 printf("%d pre : %d in : %.2f\n", i, pre[i], cost[i]); 55 puts(""); 56 #endif 57 cost[root] = 0; 58 for (i = 0; i < v; i++){ 59 min_cost += cost[i]; 60 fold[i] = vis[i] = -1; 61 if (cost[i] > inf && i != root) return false; 62 } 63 64 cnt = 0; 65 for (i = 0; i < v; i++){ 66 j = i; 67 vis[i] = i; 68 for (j = pre[j]; j != root && vis[j] != i && fold[i] == -1; j = pre[j]) vis[j] = i; 69 if (j == root || fold[j] != -1) continue; 70 for (s = j, fold[s] = cnt, s = pre[s]; s != j; s = pre[s]) fold[s] = cnt; 71 cnt++; 72 } 73 if (!cnt) return true; 74 for (i = 0; i < v; i++){ 75 if (fold[i] == -1) fold[i] = cnt++; 76 } 77 #ifndef ONLINE_JUDGE 78 for (i = 0; i < v; i++) printf("fold %d : %d\n", i, fold[i]); 79 #endif 80 for (i = 0; i < e; i++){ 81 s = E[i].b; 82 t = E[i].e; 83 84 E[i].b = fold[s]; 85 E[i].e = fold[t]; 86 if (E[i].b != E[i].e){ 87 E[i].c -= cost[t]; 88 } 89 } 90 v = cnt; 91 root = fold[root]; 92 } 93 } 94 95 96 bool deal(){ 97 int n, m; 98 int b, e; 99 100 if (scanf("%d%d", &n, &m) == EOF) return false; 101 for (int i = 0; i < n; i++){ 102 scanf("%lf%lf", &P[i].x, &P[i].y); 103 } 104 for (int i = 0; i < m; i++){ 105 scanf("%d%d", &b, &e); 106 b--; e--; 107 E[i].b = b; 108 E[i].e = e; 109 E[i].c = dis(P[b], P[e]); // coordinate transform 110 } 111 if (make_tree(0, n, m)){ 112 printf("%.2f\n", min_cost); 113 } 114 else puts("poor snoopy"); 115 116 return true; 117 } 118 119 int main(){ 120 #ifndef ONLINE_JUDGE 121 freopen("in", "r", stdin); 122 #endif 123 while (deal()); 124 125 return 0; 126 }
——written by Lyon