USACO 3.1.1 Agri-Net

标准的最小生成树

用了Kruskal算法,写了一个可以以后用的并查集类

View Code
  1 /*
  2 ID: xjtuacm1
  3 PROG: agrinet
  4 LANG: C++
  5 */
  6 #include<iostream>
  7 #include<stack>
  8 #include<cstring>
  9 #include<cstdio>
 10 #include<queue>
 11 #include<algorithm>
 12 #include<set>
 13 #include<map>
 14 #include<vector>
 15 #include<cmath>
 16 using namespace std;
 17 const int MAXDIS = 100000 + 10;
 18 const int N = 100;
 19 const int M = N * (N - 1) / 2;
 20 
 21 int n, m;
 22 int e;
 23 int u[M], v[M], w[M];
 24 
 25 int wr[M];
 26 
 27 void initGraph()
 28 {
 29     e = 0;
 30 }
 31 
 32 void addEdge(int x, int y, int cost)
 33 {
 34     u[e] = x;
 35     v[e] = y;
 36     w[e++] = cost;
 37 }
 38 
 39 class UnionFind
 40 {
 41     int n;
 42     int fa[N];
 43     int r[N];
 44 
 45 public:
 46     UnionFind(int nn)
 47         : n(nn)
 48     {
 49         init();
 50     }
 51 
 52     void init()
 53     {
 54         memset(r, 0, sizeof(r));
 55         for(int i = 0; i!= n; i++)
 56             fa[i] = i;
 57     }
 58 
 59     int Find(int x)
 60     {
 61         if(x != fa[x])
 62         {
 63             fa[x] = Find(fa[x]);
 64         }
 65         return fa[x];
 66     }
 67 
 68     void Union(int x, int y)
 69     {
 70         Link(Find(x), Find(y));
 71     }
 72 private:
 73     void Link(int x, int y)
 74     {
 75         if(r[x] > r[y])
 76         {
 77             fa[y] = x;
 78         }
 79         else
 80         {
 81             fa[x] = y;
 82             if(r[x] == r[y])
 83                 r[y]++;
 84         }
 85     }
 86 };
 87 
 88 bool cmp(int a, int b)
 89 {
 90     return w[a] < w[b];
 91 }
 92 
 93 int kruskal()
 94 {
 95     UnionFind uf(n);
 96     for(int i = 0; i!= m; i++)
 97         wr[i] = i;
 98     int ret = 0;
 99 
100     sort(wr, wr+m, cmp);
101 
102     for(int i = 0; i!= m; i++)
103     {
104         int ed = wr[i];
105         if(uf.Find(u[ed]) != uf.Find(v[ed]))
106         {
107             ret += w[ed];
108             uf.Union(u[ed], v[ed]);
109         }
110     }
111 
112     return ret;
113 }
114 
115 int main(int argc, char *argv[])
116 {
117 #ifdef ACM
118     freopen("in", "r", stdin);
119 #else
120     freopen("agrinet.in", "r", stdin);
121     freopen("agrinet.out", "w", stdout);
122 #endif // ACM
123 
124     scanf("%d", &n);
125     m = n * (n - 1) / 2;
126     for(int i = 0; i!= n; i++)
127         for(int j = 0; j!= n; j++)
128         {
129             int t;
130             scanf("%d", &t);
131             if(i > j)
132                 addEdge(i, j, t);
133         }
134 
135     printf("%d\n", kruskal());
136 
137     return 0;
138 }

 

转载于:https://www.cnblogs.com/tech-cabin/archive/2013/02/15/2912926.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值