Kruskal 2015百度之星初赛2 HDOJ 5253 连接的管道

 

题目传送门

 1 /*  2  最小生成树(Kruskal):以权值为头,带入两个端点,自然的排序;感觉结构体的并查集很好看  3  注意:题目老头要的是两个农田的高度差,中文水平不好,题意理解成和平均值的高度差!  4 */  5 #include <cstdio>  6 #include <algorithm>  7 #include <cstring>  8 #include <cmath>  9 #include <vector> 10 #include <queue> 11 #include <set> 12 using namespace std; 13 14 const int MAXN = 1e3 + 10; 15 const int MAXM = 1e2 + 10; 16 const int INF = 0x3f3f3f3f; 17 int n, m; 18 int a[MAXN][MAXN]; 19 vector<pair<int, int> > G[MAXM]; 20 struct UF 21 { 22 int rt[MAXN*MAXN]; 23 void init(void) {memset (rt, -1, sizeof (rt));} 24 25 int Find(int x) {return (rt[x] == -1) ? x : rt[x] = Find (rt[x]);} 26 27 void Union(int x, int y) 28  { 29 x = Find (x); y = Find (y); 30 if (x > y) rt[y] = x; 31 else if (x < y) rt[x] = y; 32  } 33 34 bool same(int x, int y) {return Find (x) == Find (y);} 35 }uf; 36 37 int Kruskal(void) 38 { 39  uf.init (); 40 int ans = 0; 41 for (int i=0; i<=100; ++i) 42  { 43 for (int j=0; j<G[i].size (); ++j) 44  { 45 int u = G[i][j].first; int v = G[i][j].second; 46 if (!uf.same (u, v)) {uf.Union (u, v); ans += i;} 47  } 48  } 49 50 return ans; 51 } 52 53 int get_id(int i, int j) {return (i - 1) * m + j;} 54 55 int main(void) //2015百度之星初赛2 HDOJ 5253 连接的管道 56 { 57 int t, cas = 0; scanf ("%d", &t); 58 while (t--) 59  { 60 scanf ("%d%d", &n, &m); 61 for (int i=0; i<=100; ++i) G[i].clear (); 62 63 for (int i=1; i<=n; ++i) 64  { 65 for (int j=1; j<=m; ++j) 66  { 67 scanf ("%d", &a[i][j]); 68 if (i > 1) {G[abs (a[i][j] - a[i-1][j])].push_back (make_pair (get_id (i, j), get_id (i-1, j)));} 69 if (j > 1) {G[abs (a[i][j] - a[i][j-1])].push_back (make_pair (get_id (i, j), get_id (i, j-1)));} 70  } 71  } 72 73 printf ("Case #%d:\n", ++cas); 74 printf ("%d\n", Kruskal ()); 75  } 76 77 return 0; 78 } 79 80 81 /* 82 2 83 4 3 84 9 12 4 85 7 8 56 86 32 32 43 87 21 12 12 88 2 3 89 34 56 56 90 12 23 4 91 */

 

你可能感兴趣的:(百度)