[啊哈算法]镖局运镖(最小生成树)
作者:互联网
Description
最近小哼迷上了《龙门镖局》,从恰克图道武夷山,从张家口道老河口,从迪化道佛山,从蒙自道奉天......古代镖局的运镖,也就是现在的物流。镖局每到一个地方开展业务,都需要堆运镖途中的绿林好汉进行打点(不给钱就不让过路)。好说话的打点费就比较低,不好说话的打点费就比较高。城镇类似如下,顶点是城镇编号,边上的值表示这条道路上打点绿林好汉需要的银子数。
请你帮镖局算算,如果从1号城镇出发,遍历每个城镇最少需要准备多少打点银子?
Input
输入第一行包括两个正整数n,m。n代表城镇个数,m表示道路个数(1 < n,m < 100)。
后面的m行分别包含三个正整数a,b,c,表示在从城镇a 到 城镇b的道路上需要交纳的银子数。
Output
输出从1号城镇出发,遍历每个城镇最少需要准备的银子数。
Sample Input
6 9 2 4 11 3 5 13 4 6 3 5 6 4 2 3 6 4 5 7 1 2 1 3 4 9 1 3 2
Sample Output
19
这是用并查集的方法来找的最小生成树。
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 struct edge{//用结构体来存储边的信息 5 int u; 6 int v; 7 int w; 8 }; 9 int n,m; 10 int f[103]; 11 int num=0,sum=0;//num表示边的数量,sum表示最小生成树的总权 12 int cmp(edge x,edge y){//自定义排序方式 13 return x.w<y.w; 14 } 15 int getf(int x){//找祖宗的函数 16 if(f[x]==x) 17 return x; 18 else{ 19 f[x]=getf(f[x]); 20 return f[x]; 21 } 22 } 23 int merge(int x,int y){//合并两个集合 24 int t1=getf(x); 25 int t2=getf(y); 26 if(t1!=t2){ 27 f[t2]=t1; 28 return 1; 29 } 30 return 0; 31 } 32 int main(){ 33 struct edge e[103]; 34 cin>>n>>m; 35 for(int i=1;i<=m;i++){ 36 cin>>e[i].u>>e[i].v>>e[i].w; 37 } 38 for(int i=1;i<=n;i++){ 39 f[i]=i; 40 } 41 sort(e+1,e+m+1,cmp);//stl排序 42 for(int i=1;i<=m;i++){//核心语句:先遍历每条边 43 if(merge(e[i].u,e[i].v)){//如果这两个点没有相通 44 num++;//增加最小生成树的一条边 45 sum+=e[i].w;//总权值增加 46 } 47 if(num==n-1){//最小生成树共有n-1条边 48 break; 49 } 50 } 51 cout<<sum; 52 return 0; 53 }
标签:镖局,打点,运镖,int,城镇,银子,edge,啊哈 来源: https://www.cnblogs.com/fate-/p/12248540.html