hdu 1102
题意:有n个村子与很多路,有些路已经修好了,求最小路程把所有村子连起来。
题解:用Kruskal算法,提前把已经修好的路合并。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int n,q,Map[110][110],f[110],tot;
struct node{
int from,to,len;
}edge[21000];
bool cmp(node x,node y){
return x.len<y.len;
}
int find(int x){
int r = x;
while(f[r] != r){
r = f[r];
}
int i = x, j;
while(i != r){
j = f[i];
f[i] = r;
i = j;
}
return r;
}
void join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy) f[fx]=fy;
}
int Kruskal(){
int ans=0,k1=0;
for(int j=0;j<tot;j++){
//printf("%d %d\n",find(edge[j].from),find(edge[j].to));
if(find(edge[j].from)!=find(edge[j].to)){
join(edge[j].from,edge[j].to);
ans+=edge[j].len;
}
}
return ans;
}
int main(){
while(scanf("%d",&n)!=EOF){
tot=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&Map[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++){
edge[tot].from=i,edge[tot].to=j,edge[tot].len=Map[i][j];
tot++;
}
scanf("%d",&q);
for(int i=1;i<=n;i++) f[i]=i;
while(q--){
int a,b;
scanf("%d%d",&a,&b);
join(a,b);
}
sort(edge,edge+tot,cmp);
printf("%d\n",Kruskal());
}
return 0;
}