1. 程式人生 > >每日一題(01.05)

每日一題(01.05)

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; }