Description
现有N个村庄,编号1~N。村庄可以通过道路相连。如果村A可以直接到达B或者经过另一个村庄而到达村庄B,则称A和B是相连的。已知这些村庄之间已经有一些道路相连了,请你找到一种修路方案,使所有村庄都是相连的,且使得建造的总道路长度最短。
Input
多行输入。第一行一个整数N(3<=N<=100),表示村庄的数量。然后是N行N列的距离矩阵,即第i行第j列的整数d表示村庄i到村庄j的距离(1<=d<=1000)。
然后一行是一个整数Q(0<=Q<=N*(N+1)/2)。接下来Q行,每行包含两个整数a和b(1<=a<b<= N),表示村庄a和村庄b之间的道路已经建成。
Output
最小建造总长度。
Sample Input
3
0 990 692
990 0 179
692 179 0
1
1 2
Sample Output
179
Reference code
#include <iostream>
#include <algorithm>
using namespace std;
int connect_to[100000];
struct distance{
int len;
int x;
int y;
}d[10000];
int cmp(struct distance a,struct distance b){
return a.len < b.len;
}
int connect(int i){
if(connect_to[i]==i)
return i;
return connect_to[i]=connect(connect_to[i]);
}
int main(){
int villages;
while(cin>>villages){
int j=0;
for(int x=0;x<villages;x++)
for(int y=0;y<villages;y++){
cin>>d[j].len;
d[j].x=x;
d[j].y=y;
j++;
}
sort(d,d+j,cmp);
for(int i=0;i<villages;i++)
connect_to[i]=i;
int built_roads;
cin>>built_roads;
int x,y;
while(built_roads--){
cin>>x>>y;
x=connect(x-1);
y=connect(y-1);
if(x!=y)
connect_to[x]=connect_to[y];
}
int sum=0;
for(int i=0;i<j;i++){
if (d[i].len>0){
x=connect(d[i].x);
y=connect(d[i].y);
if(x!=y){
sum+=d[i].len;
connect_to[x]=connect_to[y];
}
}
}
cout<<sum<<endl;
}
return 0;
}