• hdoj 1863 畅通工程


    并查集+最小生成树

    畅通工程

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 19824    Accepted Submission(s): 8449


    Problem Description
    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
     
    Input
    测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
    行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
     
    Output
    对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
     
    Sample Input
    3 3
    1 2 1
    1 3 2
    2 3 4
    1 3
    2 3 2
    0 100
     
    Sample Output
    3
    ?
     
    附上两种算法
    kruskal算法
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int set[110];
    struct record
    {
    	int beg;
    	int end;
    	int money;
    }s[11000];
    int find(int fa)
    {
    	int ch=fa;
    	int t;
    	while(fa!=set[fa])
    	fa=set[fa];
    	while(ch!=fa)
    	{
    		t=set[ch];
    		set[ch]=fa;
    		ch=t;
    	}
    	return fa;
    }
    void mix(int x,int y)
    {
    	int fx,fy;
    	fx=find(x);
    	fy=find(y);
    	if(fx!=fy)
    	set[fx]=fy;
    }
    bool cmp(record a,record b)
    {
    	return a.money<b.money;
    }
    int main()
    {
    	int city,road,n,m,j,i,sum;
    	while(scanf("%d",&road)&&road!=0)
    	{
    		scanf("%d",&city);
    		for(i=0;i<road;i++)
    		{
    			scanf("%d%d%d",&s[i].beg,&s[i].end,&s[i].money);
    		}
    		for(i=1;i<=city;i++)
    		set[i]=i;
    		sort(s,s+road,cmp);
    		sum=0;
    		for(i=0;i<road;i++)
    		{
    			if(find(s[i].beg)!=find(s[i].end))
    			{
    				mix(s[i].beg,s[i].end);
    				sum+=s[i].money;
    			}
    		}
    		j=0;
    		for(i=1;i<=city;i++)
    		{
    			if(set[i]==i)
    			j++;
    			if(j>1)
    			break;
    		}
    		if(j>1)
    		printf("?
    ");
    		else
    		printf("%d
    ",sum);
    	}
    	return 0;
    }
    

      prime算法

    #include<stdio.h>
    #include<string.h>
    #define INF 0x3f3f3f
    int lowcost[110];//此数组用来记录第j个节点到其余节点最少花费 
    int map[110][110];//用来记录第i个节点到其余n-1个节点的距离 
    int visit[110];//用来记录最小生成树中的节点 
    int city;
    void prime()
    {
    	int min,i,j,next,mincost=0;
    	memset(visit,0,sizeof(visit));//给最小生成树数组清零 
    	for(i=1;i<=city;i++)
    	{
    		lowcost[i]=map[1][i];//初始化lowcost数组为第1个节点到剩下所有节点的距离 
    	}
    	visit[1]=1;//选择第一个点为最小生成树的起点 
    	for(i=1;i<city;i++)
    	{
    		min=INF;
    		for(j=1;j<=city;j++)
    		{
    			if(!visit[j]&&min>lowcost[j])//如果第j个点不是最小生成树中的点并且其花费小于min 
    			{
    				min=lowcost[j];
    				next=j;//记录下此时最小的位置节点 
    			}
    		}
    		if(min==INF)
    		{
    			printf("?
    ");
    			return ;
    		}
    		mincost+=min;//将最小生成树中所有权值相加 
    		visit[next]=1;//next点加入最小生成树 
    		for(j=1;j<=city;j++)
    		{
    			if(!visit[j]&&lowcost[j]>map[next][j])//如果第j点不是最小生成树中的点并且此点处权值大于第next点到j点的权值 
    			{
    				lowcost[j]=map[next][j];         //更新lowcost数组 
    			}
    		}
    	}
    	printf("%d
    ",mincost);
    }
    int main()
    {
    	int road;
    	int j,i,x,y,c;
    	while(scanf("%d%d",&road,&city)&&road!=0)
    	{
    		memset(map,INF,sizeof(map));//初始化数组map为无穷大 
    		while(road--)
    		{
    		    scanf("%d%d%d",&x,&y,&c);
    		    map[x][y]=map[y][x]=c;//城市x到y的花费==城市y到想的花费 
    		}
    		prime();
    	}
    	return 0;
    }
    

      

      

  • 相关阅读:
    Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
    利用Docker构建开发环境
    MyEclipse 8.6.1 制作绿色版
    Tomcat,JBoss与JBoss Web
    oracle,mysql,SqlServer三种数据库的分页查询
    Tomcat+JSP经典配置实例
    [转载]JDK自带的实用工具——native2ascii.exe
    用sql删除数据库重复的数据的方法
    Dom4j 使用简介(全而好的文章)
    Java操作XML文件 dom4j 篇
  • 原文地址:https://www.cnblogs.com/tonghao/p/4487383.html
Copyright © 2020-2023  润新知