C - 畅通工程 (HDU - 1863)

- 题目大意

    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。因此求出最少的成本为多少?

- 解题思路

    最小生成树的问题,用kruskal算法,kruskal算法是一种贪心策略,每次放长度(本题可以看做是建路的成本)最小的边,如果两个点属于同一个集合就不放,否则会构成环,每放一个点我们记录一次,最后把所有点都连通了就结束算法。 

- 代码

    

#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 1e5 + 50;
int fa[MAX];

struct Edge {
	int u, v, w;
	bool operator<(const Edge &rhs)const {
		return w < rhs.w;
	}
}e[MAX];
void init(int n)
{
	for (int i = 1; i <= n; i++)
		fa[i] = i;
}

int find(int x)
{
	if (x == fa[x])
		return x;
	else
	{
		return fa[x] = find(fa[x]);
	}
}

bool Union(int x, int y)
{
	int fx = find(x), fy = find(y);
	if (fx == fy)
		return false;
	else
	{
		fa[fx] = fy;
		return true;
	}
}

int kruskal(int n, int m)
{
	sort(e, e + m);
	init(n);
	int sum = 0;
	for (int i = 1; i <= m; i++)
	{
		int u = e[i].u, v = e[i].v, w = e[i].w;
		if (Union(u, v))
		{
			sum += w;
		}
	}
	return sum;
}
int main()
{
	int n,m,tmp,sum;
	while (cin >> n >> m)
	{
		if (n == 0)
			break;
		for (int i = 1; i <= n; i++)
			cin >> e[i].u >> e[i].v >> e[i].w;
		tmp = kruskal(m, n);
		sum = 0;
		for (int i = 1; i <= m; i++)
		{
			if (fa[i] == i)
				sum++;
		}
		if (sum > 1)
			cout << "?" << endl;
		else
		{
			cout << tmp << endl;
		}
	}
	return 0;
}

  

posted @ 2018-02-15 13:22  Alpacaddhh  阅读(114)  评论(0编辑  收藏  举报