模板题zoj1372(最小生成树kruscal/并查集)

题目链接:zoj1372

虽然这是一道十足的模板题,但是理解题目的时候还是有点脑筋急转弯的感觉的——因为题目中说“note that there may exist many possible routes between given points”,这和以前印象中的经典图稍微有点区别。

不过细想一下,其实根本不用理会两个点之间是一条路还是多条路——因为在kruscal算法(或者prim算法)中,只要某两个点被包含在生成树中,之后就不用再考虑这两个点的事了。所以两个点之间多个边也没关系

———或者,实在觉得变扭,就把两个点之间的多条边用最短的那条代替,也许

简洁利落的代码:

#include<bits/stdc++.h>
#define inf 1e9
using namespace std;

//int net[51][51];
typedef struct connection{
   int x;
   int y;
   int w;
}Conn;
Conn arc[100000];
int root[51];

bool cmp(Conn x,Conn y){
    return x.w<y.w;
}

int findRoot(int x){
   if(root[x]==x)
      return x;
   else
      return findRoot(root[x]);
}
int kruscal(Conn conn){
 int a=findRoot(conn.x);
 int b=findRoot(conn.y);

 if(a!=b){
  root[a]=b;
  return conn.w;
 }
 else
 return 0;
}
int main(){
int n;//点的数目
int m;//路径数目
int sum;
while(cin>>n>>m&&n){


    sum=0;
    for(int i=1;i<=n;i++)
       root[i]=i;

    for(int i=1;i<=m;i++)
       cin>>arc[i].x>>arc[i].y>>arc[i].w;
       sort(arc+1,arc+1+m,cmp);



   for(int i=1;i<=m;i++){
       sum+=kruscal(arc[i]);
   }
   cout<<sum<<endl;
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/k0_0k/article/details/81255401