zoukankan      html  css  js  c++  java
  • POJ 2421 Constructing Roads(Kruskal算法)

    题意:给出n个村庄之间的距离,再给出已经连通起来了的村庄。求把所有的村庄都连通要修路的长度的最小值。

    思路:Kruskal算法

    课本代码:

    //Kruskal算法
    #include<iostream>
    using namespace std;
    
    int fa[120];
    int get_father(int x){
    	return fa[x]=fa[x]==x?x:get_father(fa[x]);//判断两个节点是否属于一颗子树(并查集)
    }
    int main(){
    	int n;
    	int p[120][120];
    	while(scanf("%d",&n)!=EOF){
    		int i,j,k,m;
    		for(i=0;i<n;i++)
    			for(j=0;j<n;j++)
    				scanf("%d",&p[i][j]);
    			for(i=0;i<n;i++) fa[i]=i;
    			scanf("%d",&m);
    			while(m--){
    				int a,b;
    				scanf("%d%d",&a,&b);
    				fa[get_father(a-1)]=get_father(b-1);// a  合并到 b
    			}
    			int ans=0;
    			for(k=1;k<=1000;k++)// kruskal 算法,这里每个长度都进循环,若加一个长度存在的标记,可以节省时间
    				for(i=0;i<n;i++)
    					for(int j=0;j<n;j++)
    						if(p[i][j]==k &&get_father(i)!=get_father(j)){
    							fa[fa[i]]=fa[j];//合并两颗子树(并查集)
    							ans+=k;
    						}
    			printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    代码2:加了mark标记长度是否存在,代码中-------------为添加部分

    //Kruskal算法
    #include<iostream>
    using namespace std;
    
    int fa[120];
    int mark[1010];//-------------标记长度是否存在
    int get_father(int x){
    	return fa[x]=fa[x]==x?x:get_father(fa[x]);//判断两个节点是否属于一颗子树(并查集)
    }
    int main(){
    	int n;
    	int p[120][120];
    	while(scanf("%d",&n)!=EOF){
    		memset(mark,0,sizeof(mark));
    		int i,j,k,m;
    		for(i=0;i<n;i++)
    			for(j=0;j<n;j++){
    				scanf("%d",&p[i][j]);
    				mark[p[i][j]]=1;//-------------把当前的长度标记一下
    			}
    			for(i=0;i<n;i++) fa[i]=i;
    			scanf("%d",&m);
    			while(m--){
    				int a,b;
    				scanf("%d%d",&a,&b);
    				fa[get_father(a-1)]=get_father(b-1);// a  合并到 b
    			}
    			int ans=0;
    			for(k=1;k<=1000;k++)// kruskal 算法
    				if(mark[k]){// -------------------长度存在的时候,再进入这个循环				
    					for(i=0;i<n;i++)
    						for(int j=0;j<n;j++)
    							if(p[i][j]==k &&get_father(i)!=get_father(j)){
    								fa[fa[i]]=fa[j];//合并两颗子树(并查集)
    								ans+=k;
    							}
    				}
    				printf("%d
    ",ans);
    	}
    	return 0;
    }
    



  • 相关阅读:
    Java 8 Stream流编程学习
    AMD R5 2400G插帧教程
    GCC编译Win图形程序不显示控制台方法
    Linux程序守护脚本
    远程桌面软件RDCMan汉化版
    Java基础知识点
    Java的String类常用方法
    Apache Commons 相关工具类使用
    基于OpenCV的双目视觉匹配测距系统
    异想家Ubuntu安装的软件
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4477423.html
Copyright © 2011-2022 走看看