POJ-2485 Highways---最小生成树中最大边

题目链接:

https://vjudge.net/problem/POJ-2485

题目大意:

求最小生成树中的最大边

思路:

是稠密图,用prim更好,但是规模不大,kruskal也可以过

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<queue>
  7 #include<stack>
  8 #include<map>
  9 #include<sstream>
 10 using namespace std;
 11 typedef long long ll;
 12 const int maxn = 3e5 + 10;
 13 const int INF = 1 << 30;
 14 int dir[4][2] = {1,0,0,1,-1,0,0,-1};
 15 int T, n, m, x;
 16 struct edge
 17 {
 18     int u, v, w;
 19     bool operator <(const edge& a)const
 20     {
 21         return w < a.w;
 22     }
 23 };
 24 edge a[maxn];
 25 int par[600], high[600];
 26 //初始化n个元素
 27 void init(int n)
 28 {
 29     for(int i = 0; i < n; i++)
 30     {
 31         par[i] = i;
 32         high[i] = 0;
 33     }
 34 }
 35 //查询树的根
 36 int Find(int x)
 37 {
 38     return par[x] == x ? x : par[x] = Find(par[x]);//路径压缩
 39 }
 40 void unite(int x, int y)
 41 {
 42     x = Find(x);
 43     y = Find(y);
 44     if(x == y)return;
 45     if(high[x] < high[y])par[x] = y;//y的高度高,将x的父节点设置成y
 46     else
 47     {
 48         par[y] = x;
 49         if(high[x] == high[y])high[x]++;
 50     }
 51 }
 52 bool same(int x, int y)
 53 {
 54     return Find(x) == Find(y);
 55 }
 56 void kruskal(int n, int m)//点数n,边数m
 57 {
 58     int ans = 0;//mst权值
 59     int num= 0;//已经选择的边的边数
 60     sort(a, a + m);//边进行排序
 61     init(n);//初始化并查集
 62     for(int i = 0; i < m; i++)
 63     {
 64         int u = a[i].u;
 65         int v = a[i].v;
 66         if(Find(u - 1) != Find(v - 1))//图最开始的下标是1,并查集是0
 67         {
 68             //printf("%d %d %d\n", u, v, a[i].w);
 69             //sum_mst += a[i].w;
 70             ans = max(ans, a[i].w);
 71             num++;
 72             unite(u - 1, v - 1);
 73         }
 74         if(num >= n - 1)break;
 75     }
 76     //printf("weight of mst is %d\n", sum_mst);
 77     printf("%d\n", ans);
 78 }
 79 int main()
 80 {
 81     cin >> T;
 82     while(T--)
 83     {
 84         scanf("%d", &n);
 85         int x;
 86         int tot = 0;
 87         for(int i = 1; i <= n; i++)
 88         {
 89             for(int j = 1; j <= n; j++)
 90             {
 91                 scanf("%d", &x);
 92                 if(i == j)continue;
 93                 a[tot].u = i;
 94                 a[tot].v = j;
 95                 a[tot++].w = x;
 96             }
 97         }
 98         kruskal(n, tot);
 99     }
100     return 0;
101 }

 

posted @ 2018-04-05 17:17  _努力努力再努力x  阅读(247)  评论(0编辑  收藏  举报