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

    Description

    There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.

    We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.

    Input

    The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.

    Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.

    Output

    You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.

    Sample Input

    3
    0 990 692
    990 0 179
    692 179 0
    1
    1 2
    

    Sample Output

    179

    本人理解其实就是结合并查集的图的应用

    #include<iostream>
    #include <algorithm>
    using namespace std;
    
    int fa[120];
    int get_father(int x)
    {
    	
    	if(fa[x]==x)
    		return x;
    	else
    		return  fa[x]=get_father(fa[x]);
    	//	return fa[x]=fa[x]==x ?x:get_father(fa[x]);//判断两个节点是否属于一颗子树(并查集)
    }
    int main()
    {
    	int temp[15000],tem=0;
    	int n;
    	int p[120][120];
    	while(scanf("%d",&n)!=EOF)
    	{
    		tem=0;
    		int i,j,k,m;
    		for(i=0;i<n;i++)
    			for(j=0;j<n;j++)
    			{
    				scanf("%d",&p[i][j]);
    			    temp[ p[i][j] ]=1;        //记录下在两个相邻的长度中有这个值
    				                           //其实这个步骤可以没有,并且正宗的Kruskal算法好像也没有这个约束条
    				                           // 设这个变量就是为了在后面遍历查找的时候会快一点,
    				                          //但是事实表明,没有快,可能是后台的测试数据太少了。。。
    			}
    		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;
    		<span style="color:#ff0000;">for(k=0;k<=1000;k++)// kruskal 算法
    		{
    			if(temp[k]==1)//如果这个长度在路径中存在,如果直接没有当前距离的话就没有必要查找了
    			{
    			for(i=0;i<n;i++)
    				for(int j=0;j<n;j++)
    					if(p[i][j]==k && get_father(i)!=get_father(j))//当出现当前距离并且i和j未连接时,合并两个集合
    					{
    						fa[fa[i]]=fa[j];               //合并两颗子树(并查集)
    						ans+=k;
    					}
    			}
    		}
    </span>		printf("%d
    ",ans);
    	}
    	return 0;
    }
    



     

  • 相关阅读:
    day22 面向对象
    springMVC中 POST 请求数据变乱码问题
    Handler dispatch failed; nested exception is java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyResultSet.isClosed()Z is abstract
    java.sql.SQLException: Unknown system variable 'tx_isolation'
    Mysql命令
    paas相关,添加ing
    Angular2中实现基于TypeScript的对象合并方法:extend()
    NgStyle和NgIf控制HTML标签显示的区别
    执行ng build --prod --aot命令报错
    JavaScript中的小陷阱(不定期更新。。)
  • 原文地址:https://www.cnblogs.com/zswbky/p/5432090.html
Copyright © 2011-2022 走看看