您的位置:首页 > 其它

练习四1001畅通工程

2016-06-28 11:56 543 查看


题意:第一行那是小镇的数目,下面三行分别是第一个小镇到第一个的距离,到第二个的距离,以此类推。再输入有几个联通的点集(生成树),再一行代表哪两个点连接。

思路:

1.用一个二维数组代表距离,并且形成了映射关系,a[m-1][n-1]代表m镇到n镇的距离。

2.就是求一个最小生成树,使用Kruskal算法,没到根节点不同的地方就将权值相加,输出即可

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 105;
int root
;
int a

;
int find(int x)//查找
{
if (x != root[x])
root[x] = find(root[x]);
return root[x];
}
struct node
{
int x, y, v;
}e[N*(N - 1) / 2];
int cmp(node e1, node e2)
{
return e1.v<e2.v;
}
int main()
{
int n;
cin >> n;
int m= n;
for (int i = 0; i < n; ++i)
root[i] = i;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
cin >> a[i][j];//a[i][j]表示每个点之间的距离
int num;
cin >> num;
int x1, x2;
for (int i = 0; i <num; ++i)//将以连接的点的距离赋0
{
cin >> x1 >> x2;
a[x1 - 1][x2 - 1] = 0;
}
int t = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
{
e[t].x = i;
e[t].y = j;
e[t].v = a[i][j];
++t;
}
int sum = 0;
sort(e, e +t, cmp);
for (int i = 0; i <t; ++i)//合并
{
int x = find(e[i].x);
int y = find(e[i].y);
if (x != y)
{
sum+= e[i].v;
root[x] = y;
--m;//每次将m减一,作为flag

if(m==1)
{
cout <<sum<< endl;
}
}

}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: