F. Constructing Roads

There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.

We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.

 

Input

The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.

 

Output

You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.

 

Sample Input

3
0 990 692
990 0 179
692 179 0
1
1 2

Sample Output

179

题意:
有N个村庄,编号从1到N。现需要在这N个村庄之间修路,使得任何两个村庄之间都可以连通。称A、B两个村庄是连通的,
当且仅当A与B有路直接连接,或者存在村庄C,使得A和C两村庄之间有路连接,且C和B之间有路连接。已知某些村庄之间已经有
路直接连接了,试修建一些路使得所有村庄都是连通的、且修路总长度最短。
#include <cstdio>
#include <iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=;
int p[MAXN];
bool sum[MAXN];
int m[MAXN][MAXN];
struct node
{
int x,y,l;
}a[];
bool cmp(node a,node b)
{
return a.l<b.l;
}
int Find(int x)
{
return x==p[x]?x:(p[x]=Find(p[x]));
}
int Union(int R1,int R2)
{ int r1=Find(R1);
int r2=Find(R2);
if(r1!=r2)
{
p[r1]=r2;
return ;
}
else return ;
}
int main()
{
int n;
int cnt=,i,j;
while(~scanf("%d",&n))
{
cnt =;
memset(sum,,sizeof(sum));
for(i=;i<=n;i++)
p[i]=i;
for(i=;i<=n;i++)
for( j=;j<=n;j++)
scanf("%d",&m[i][j]);
int t,c,b;
scanf("%d",&t);
while(t--) //将已经修好的路长度清零
{
scanf("%d%d",&c,&b);
m[c][b]=m[b][c]=;
}
int k=;
for(i=;i<=n;i++)
{
for(j=+i;j<=n;j++)
{
a[k].x=i;
a[k].y=j;
a[k].l=m[i][j];
k++;
}
}
sort(a,a+k,cmp); for(i=;i<k;i++)
{
if(Union(a[i].x,a[i].y)==)
cnt+=a[i].l;
}
printf("%d\n",cnt);
}
return ;
}

最新文章

  1. OpenMesh 将默认的 float 类型改为 double 类型
  2. Mac安装软件报“打不开。。。,因为它来自身份不明的开发者”的解决办法
  3. Android Studio tips1
  4. 安装pods 遇到的坑
  5. 2013长沙 G Graph Reconstruction (Havel-Hakimi定理)
  6. ACM: 畅通工程-并查集-解题报告
  7. [转]SIFT特征提取分析
  8. ResultSetMetaData和DatabaseMetaData实现数据库中属性,属性值,属性所赋值的获取等
  9. 深入JS第一天:原型和它的小伙伴们(一)
  10. PHP来实现文件上传
  11. elasticSearch(5.3.0)的评分机制的研究
  12. SimpleDateFormat 常规用法
  13. toString()方法细节
  14. HighCharts之2D柱状图、折线图和饼图的组合图
  15. 腾讯2017年暑期实习生编程题【算法基础-字符移位】(C++,Python)
  16. 3款网页jQuery抽奖实例演示
  17. [翻译] ASP.NET Core 利用 Docker、ElasticSearch、Kibana 来记录日志
  18. leetcode python 011
  19. P1616疯狂的采药
  20. 锐捷 Fat/Fit Ap切换

热门文章

  1. Java 排序算法实现
  2. C#中Trim()、TrimStart()、TrimEnd()的用法
  3. 【bzoj1076】[SCOI2008]奖励关
  4. jQuery入门(3)事件与事件对象
  5. C和指针 第七章 可变参数
  6. 创建GitHub博客
  7. iOS 多线程
  8. ASM:《X86汇编语言-从实模式到保护模式》第9章:实模式下中断机制和实时时钟
  9. Android 笔记 day1
  10. xamarin.Android 标记1