练习四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;
}
相关文章推荐
- sqlserver数据库18456错误怎么解决?
- iOS中UIKit的外观属性及方法汇总
- ASP.NET通过第三方网站Bitly实现短链接地址程序
- 性能测试流程
- 代码片段 有很多代码工具
- SideBar
- 1006
- iOS中UIKit的外观属性及方法汇总
- iOS UITableView的分割线短15像素,移动到最左边的方法(iOS8)
- 腾讯X5内核的集成和使用
- Android Studio NDK jni 开发生成头文件和加载so库
- 冷月X
- Python-理解super函数
- 通过gradle文件进行打包
- 移动前端开发之viewport的深入理解
- android注解
- iOS cookie
- ReactJS学习系列课程(React react常用架构分析)
- 一步步教你打造3D旋转盒
- python统计日志小脚本