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 }