标准的最小生成树
用了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 }