Network

poj1861:http://poj.org/problem?id=1861

题意::求一个最小生成树,边和边权都给出了,只是输出,要求输出最大权值的边的权值,边的条数以及都是什么边
题解:直接用kruska,求最小生成树,最大边,为最后加入的边。边数为n-1;然后依次输出生成树。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 using namespace std;
 7 const int MAXN=1002;
 8 int n,m,num,pa[MAXN],top,counts[15003];//分别标记点数,边数,等 
 9 struct Node{//定义边节点 
10     int u;
11     int v;
12     int w;
13     bool operator<(const Node &a)const{
14         return w<a.w;
15     }
16 }edge[15003];
17 void UFset(){//初始化 
18     for(int i=1;i<=n;i++)
19       pa[i]=-1;
20 } 
21 int Find(int x){//查找 
22     int s;
23     for(s=x;pa[s]>=0;s=pa[s]);
24     while(s!=x){//路径压缩 
25         int temp=pa[x];
26         pa[x]=s;
27         x=pa[x];
28     }
29     return s;
30 } 
31 void Union(int R1,int R2){//合并 
32     int r1=Find(R1);
33     int r2=Find(R2);
34     int temp=pa[r1]+pa[r2];
35     if(pa[r1]>pa[r2]){
36         pa[r1]=r2;
37         pa[r2]=temp;
38     }
39     else{
40         pa[r2]=r1;
41         pa[r1]=temp;
42     }
43 }
44 void kruska(){
45       UFset();
46       num=0;top=-1;
47     for(int i=1;i<=m;i++){
48         int u=edge[i].u;
49         int v=edge[i].v;
50         if(Find(u)!=Find(v)){
51             num++;
52             Union(u,v);
53             counts[i]=top;top=i;//记录加入的边 
54         }
55         if(num>=n-1)break;
56     }    
57 }
58 void print(int gg){
59     if(counts[gg]!=-1)
60     print(counts[gg]);
61     printf("%d %d
",edge[gg].u,edge[gg].v);
62 }//依序输出生成树 
63 int main(){
64 
65         scanf("%d%d",&n,&m);
66         for(int i=1;i<=m;i++)//读取数据 
67           scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
68           sort(edge+1,edge+m+1);//注意排序,千万别忘记。 
69           kruska();
70           printf("%d
",edge[top].w);//输出最大边 
71           printf("%d
",num);//输出边数 
72           print(top);//输出生成树 
73 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3370979.html