HDU-1863

畅通工程

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


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 ?


思路:使用Prime算法或者Kruskal算法求最小生成树

我使用Prime算法,由于Prime算法的实现方式不同,可能输出?的判断条件不同,我采用的是《挑战程序设计竞赛》(第2版)的Prime算法,而其他的比如 http://blog.csdn.net/chenguolinblog/article/details/7994169 的作者的输出?的判断条件则不同


欢迎交流:

#include <cstdio>
#include <string.h>
#include<algorithm>
using namespace std;

int const INF = 0x3f3f3f3f;
int const MAX_V = 110;
int cost[MAX_V][MAX_V];//cost[u][v]表示边e=(u,v)的权值
int mincost[MAX_V];//从集合X(已经求得的生成树的顶点集合)出发的边到每个顶点的最小权值(不存在的情况下设为INF)
bool used[MAX_V];//顶点i是否包含在集合X中
int V;//顶点数

void prim()
{
	for (int i = 1; i <= V; i++)
	{
		mincost[i] = INF;
		used[i] = false;
	}
	mincost[1] = 0;
	int res = 0;

	while (true)
	{
		int v = -1;

		//从不属于X的顶点中选取从X到其权值最小的顶点
		for (int u = 1; u <= V; u++)
		{
			if (!used[u] && (v == -1 || mincost[u] < mincost[v]))v = u;
		}
		
		if (v == -1)break;
		used[v] = true;//把顶点v加入到X
		res += mincost[v];//把边的长度加到结果中
		for (int u = 1; u <= V; u++)
		{
			mincost[u] = min(mincost[u], cost[v][u]);

		}

	}

	if (res>=INF) printf("?\n");//把不存在的边加入到结果中,res比如>=INF
	else printf("%d\n", res);
}



int main()
{
	int n;
	int i=0, j=0;
	while (scanf("%d", &n) != EOF&&n)
	{
		memset(cost, INF, sizeof(cost));

		scanf("%d",&V);

		while (n--)
		{
		 scanf("%d%d", &i,&j);
		 scanf("%d", &cost[i][j]);
		 cost[j][i] = cost[i][j];//无向图
		}
		prim();
	}
	return 0;

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值