Constructing Roads
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1102
解题思路:
简单的最小生成树的应用,不过,按我以前的风格,会加个提前跳出循环的判断,但是这题不行,因为题目给出的两个点联通,有可能重复。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000;
struct Edge{
int u,v,w;
}edge[maxn];
int pa[maxn],cnt,k;
bool cmp(Edge a,Edge b){
return a.w<b.w;
}
int Find(int x){
if(pa[x] != x)
pa[x] = Find(pa[x]);
return pa[x];
}
int kruskal(){
int u,v,l = 0;
for(int i = 0; i < k; i++){
u = Find(edge[i].u);
v = Find(edge[i].v);
if(u != v){
l += edge[i].w;
pa[v] = u;
}
}
return l;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
memset(pa,-1,sizeof(pa));
int x,y;
k = 0;cnt = n;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++){
scanf("%d",&x);
if(i != j){
edge[k].u = i;
edge[k].v = j;
edge[k++].w = x;
}
}
for(int i = 0; i < k; i++)
pa[i] = i;
sort(edge,edge+k,cmp);
int q,u,v;
scanf("%d",&q);
for(int i = 0; i < q; i++){
scanf("%d%d",&x,&y);
u = Find(x-1);
v = Find(y-1);
if(u != v)
pa[v] = u;
}
printf("%d\n",kruskal());
}
return 0;
}