[板子]Kruskal

众所周知求最小生成树的两种方法:

1、Kruskal

2、Prim

这里只挂第一种,因为noip掌握第一种就够了。

两种做法的区别可以参考这个博客:http://blog.csdn.net/mollnn/article/details/52589741

 

人人都说prim简单kruskal难..但我怎么就只会kruskal呢..

下面搬个题吧:

Bessie 计划调查N (2 <= N <= 2,000)个农场的干草情况,它从1号农场出发。

农场之间总共有M (1 <= M <= 10,000)条双向道路,所有道路的总长度不超过1,000,000,000。有些农场之间存在着多条道路,所有的农场之间都是连通的。 Bessie希望计算出该图中最小生成树中的最长边的长度。

输入格式:两个整数N和M。
接下来M行,每行三个用空格隔开的整数A_i, B_i和L_i,表示A_i和 B_i之间有一条道路长度为L_i。
输出格式:一个整数,表示最小生成树中的最长边的长度。

输入样例:

  3 3
  1 2 23
  2 3 1000
  1 3 43

输出样例:
43

很容易就能看出来是最小生成树的问题。

Kruskal

维护一个并查集,并按照最短路进行加入数集。

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 using namespace std;
 5 struct node{
 6     int start,end,value;
 7 }a[10005];
 8 int cmp(node x,node y){
 9     return x.value<y.value;
10 }
11 int n,m,f[2005],ans;
12 int cha(int x){
13     if(f[x]!=x){
14         return cha(f[x]);
15     }return f[x];
16 }
17 int bing(int x,int y){
18     x=cha(x);
19     y=cha(y);
20     if(x!=y){
21         f[x]=y;
22     }
23 }
24 int main(){
25     scanf("%d%d",&n,&m);
26     for(int i=1;i<=n;i++){
27         f[i]=i;
28     }
29     int r,b,q;
30     for(int i=1;i<=m;i++){
31         scanf("%d%d%d",&r,&b,&q);
32         a[i].start=r;
33         a[i].end=b;
34         a[i].value=q;
35     }
36     sort(a+1,a+1+m,cmp);
37     for(int i=1;i<=m;i++){
38         int xxx=cha(a[i].start);
39         int yyy=cha(a[i].end);
40         if(xxx!=yyy){
41             ans=fmax(ans,a[i].value);
42             bing(a[i].start,a[i].end);
43         }
44     }
45     printf("%d",ans);
46     return 0;
47 }

 

posted @ 2017-11-04 18:51  Fylsea  阅读(213)  评论(0编辑  收藏  举报