uva 11183(最小树形图)

题意:给一张有向带权图求出最小树形图。

思路:最小树形图模版题看了大概思想http://hi.baidu.com/bin183/item/5d93ef69ceb541176895e682

学习了邝巨巨的模版,然后抄了一遍模版。a掉了这道题。

代码如下:

uva 11183(最小树形图)
  1 /**************************************************
  2  * Author     : xiaohao Z
  3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
  4  * Last modified : 2014-02-06 21:32
  5  * Filename     : uva_11183.cpp
  6  * Description     : 
  7  * ************************************************/
  8 
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <cmath>
 14 #include <algorithm>
 15 #include <queue>
 16 #include <stack>
 17 #include <vector>
 18 #include <set>
 19 #include <map>
 20 #define MP(a, b) make_pair(a, b)
 21 #define PB(a) push_back(a)
 22 
 23 using namespace std;
 24 typedef long long ll;
 25 typedef pair<int, int> pii;
 26 typedef pair<unsigned int,unsigned int> puu;
 27 typedef pair<int, double> pid;
 28 typedef pair<ll, int> pli;
 29 typedef pair<int, ll> pil;
 30 
 31 const int INF = 0x3f3f3f3f;
 32 const double eps = 1E-6;
 33 const int LEN = 1010;
 34 int Map[LEN][LEN];
 35 int pre[LEN], id[LEN], vis[LEN], in[LEN];
 36 
 37 struct E{
 38      int fr, to, val;
 39 };
 40 
 41 int zhuliu(int root, int n, int m, E edge[]){
 42     int ret = 0, u, v;
 43     while(1){
 44         for(int i=0; i<n; i++) in[i] = INF;
 45         for(int i=0; i<m; i++)
 46             if(edge[i].fr != edge[i].to && edge[i].val < in[edge[i].to]){
 47                 pre[edge[i].to] = edge[i].fr;
 48                 in[edge[i].to] = edge[i].val;
 49             }
 50         for(int i=0; i<n; i++)
 51             if(i != root && in[i] == INF) return INF;
 52         int tn = 0;
 53         memset(id, -1, sizeof id);
 54         memset(vis, -1, sizeof vis);
 55         in[root] = 0;
 56         for(int i=0; i<n; i++){
 57             ret += in[i];
 58             v = i;
 59             while(vis[v] != i && id[v] == -1 && v != root){
 60                 vis[v] = i;
 61                 v = pre[v];
 62             }
 63             if(v != root && id[v] == -1){
 64                 for(int u=pre[v]; u!=v; u=pre[u]) id[u] = tn;
 65                 id[v] = tn ++;
 66             }
 67         }
 68         if(tn == 0) break;
 69         for(int i=0; i<n; i++)if(id[i]==-1)id[i] = tn++;
 70         for(int i=0; i<m; ){
 71             v = edge[i].to;
 72             edge[i].fr = id[edge[i].fr];
 73             edge[i].to = id[edge[i].to];
 74             if(edge[i].fr != edge[i].to) edge[i++].val -= in[v];
 75             else swap(edge[i], edge[--m]);
 76         }
 77         n = tn;
 78         root = id[root];
 79     }
 80     return ret;
 81 }
 82 
 83 int main()
 84 {
 85 //    freopen("in.txt", "r", stdin);
 86 
 87     int a, b, val, T, n, m;
 88     E edge[40010];
 89     scanf("%d", &T);
 90     for(int kase = 1; kase <= T; kase++){
 91         memset(Map, INF, sizeof Map);
 92         scanf("%d%d", &n, &m);
 93         for(int i=0; i<m; i++){
 94              scanf("%d%d%d", &a, &b, &val);
 95              Map[a][b] = min(Map[a][b], val);
 96         }    
 97         int top = 0;
 98         for(int i=0; i<n; i++)
 99             for(int j=0; j<n; j++)
100                 if(Map[i][j] != INF){
101                      edge[top].fr = i;
102                      edge[top].to = j;
103                      edge[top++].val = Map[i][j];
104                 }
105         int ans = zhuliu(0, n, m, edge);
106         printf("Case #%d: ", kase);
107         if(ans == INF) printf("Possums!\n");
108         else printf("%d\n", ans);
109     }
110     return 0;
111 }
View Code

uva 11183(最小树形图)

上一篇:POJ 3140 树形dp


下一篇:[MCM]2014年美赛MCM题目原文及翻译