zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

      

  • 相关阅读:
    jmeter测试接口--form表单提交请求(解决请求传参为空的问题)
    jmeter测试接口-打开很多TCP的连接数TIME_WAIT状态(Linux环境)导致报错的解决方法
    Jmeter 事务下的if控制器和无事务下的if控制器是否有不同 (业务实现3:2的补充)
    Jmeter if控制器的使用
    Jmeter 文件格式的参数化
    CentOS7学习笔记--tomcat9环境安装
    CentOS7学习笔记--PHP环境安装
    CentOS学习笔记—启动、ROOT密码
    虚拟机硬盘扩容
    win7如何设置某个软件不弹出用户账户控制
  • 原文地址:https://www.cnblogs.com/tonghao/p/4487383.html
Copyright © 2011-2022 走看看