浙江大学机试--畅通工程

题目: 牛客网链接

概述: 给出m条道路,n个村庄,看这些道路能不能让所有村庄联通起来,如果能,输出联通的最小代价,如果不能,输出问号。

思路: 最小生成树 Kruskal算法(并查集)。
如果每个是相联通的,那么他们应该有一个共同的最终根节点。我们可以找出来一个与其他比较。用来判断是否这是个连通图

#include <iostream>
#include <algorithm> 
using namespace std;

//并查集用来存储父节点的数组 
int father[200];

struct Edge{
	int a, b, cost;
};

int find_father(int x)
{
	while( x != father[x])
	{
		x = father[x];
	}
	return x;
}

//按照花费进行排序 
bool cmp(Edge a, Edge b)
{
	return a.cost < b.cost;
}

Edge edge[200];


int main()
{
  int m, n;
  while(scanf("%d%d", &n, &m) != EOF && n != 0)
  {
  	int ans = 0;
  	for(int i = 1; i <= n; i++)
  	{
  		scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].cost);
  	}
  	
  	//按照花费进行排序 
  	sort(edge + 1, edge + 1 + n, cmp);
  	for(int i = 1; i <= m; i++) father[i] = i;
  	for(int i = 1; i <= n; i++)
  	{
  		int a = find_father(edge[i].a);
  		int b = find_father(edge[i].b);
  		if(a != b)
  		{
  		  father[a] = b;
		  ans += edge[i].cost;
  		}
  	}
  	
  	
  	//如果每个是相联通的,那么他们应该有一个共同的最终根节点。我们可以找出来一个与其他比较。用来判断是否这是个连通图 
  	bool flag = true;
  	int t = find_father(1);
  	for(int i = 2; i <= m; i++)
  	{
  		if(t != find_father(i))
  		{
  			flag = false;
  			break;
  		}
  	}
  	
  	if(flag) cout << ans << endl;
  	else cout << "?" << endl; 
  	
  }
  return 0;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值