题目大意:
洪水爆发,然后有几个幸存的城市,但这些城市并不是全都能连通的,有的城市之间有路,但是有的没有,现在政府想修路把这些城市连起来,要求编程输出修路的最少费用。
输入:
第一行输入一个正整数代表测试实例的个数,然后每个测试实例的开始输入三个整数n,m,k,分别代表城市的个数,可供选择去修的路,已经连通的城市个数。接下来输入m行,每行代表一条路,每行有3个整数p,q,c,分别代表这条路的起点和终点以及修这条路所需的费用。接下来输入k行,每行先输入一个整数,代表已经连通的城市个数t,再输入t个整数代表已连通城市的编号。
输出:
最少费用
解题思路:
这道题可以说挺简单的,因为有了前面几道题的铺垫,这道题看起来就没有前面那几道那么难了,这道题也不需要再构建模型,就是普普通通的城市从1到N编号。定义一个结构体变量去存储边的信息,将边权按从小到大排序,用克鲁斯卡尔算法求最小生成树的问题,并查集去加边,就是这样。
感想:
这一类型的题目已经做了好几道了,感觉这道题真的是挺简单的,唯一有难度的地方就是在输入那个地方,乍一开始没看明白,后来就懂了,克鲁斯卡尔加并查集完全可以解决。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
int point[100];
struct Node
{
int x, y, money;
}node[101];
int find(int x)
{
if (x != point[x])
point[x] = find(point[x]);
return point[x];
}
bool cmp(Node n1, Node n2)
{
return n1.money < n2.money;
}
int main()
{
int test,n, m, k, ans,p,q,c,t,con,con1;
cin >>test;
while (test--)
{
ans = 0;
cin >> n>>m >> k;
for (int i = 1; i <= n; i++)
point[i] = i;
for (int i = 1; i <= m; i++)
{
cin >> p >> q >> c;
node[i].x = p;
node[i].y = q;
node[i].money = c;
}
for (int i = 1; i <= k; i++)
{
cin >> t;
cin >> con;
for (int j = 1; j < t; j++)
{
cin >> con1;
point[con1] = con;
}
}
sort(node + 1, node + 1 + m, cmp);
for (int i = 1; i <= m; i++)
{
int fx = find(node[i].x);
int fy = find(node[i].y);
if (fx != fy)
{
ans += node[i].money;
point[fx] = fy;
}
}
cout << ans << endl;
}
system("pause");
return 0;
}