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;
}

浙公网安备 33010602011771号