题目链接:http://poj.org/problem?id=2421
kruskal最小生生成树+并查集,当输入已连接的点时,把他们的祖先统一
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int p[150],n,q,k;
struct all
{
int u,v,w;
}e[10010];
int cmp(all x,all y)
{
return x.w<y.w;
}
int find(int t)
{
if(p[t]!=t)
p[t]=find(p[t]);
return p[t];
}
void kruskal()
{
int ans=0;
sort(e+1,e+k+1,cmp);
for(int i=1;i<=k;i++)
{
int X=find(e[i].u);
int Y=find(e[i].v);
if(X!=Y)
{
p[X]=Y;
ans+=e[i].w;
}
}
printf("%d\n",ans);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i,j;
k=0;
for(i=1;i<=n;i++)
p[i]=i;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
int a;
scanf("%d",&a);
k++;
e[k].u=i;
e[k].v=j;
e[k].w=a;
}
scanf("%d",&q);
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
p[find(x)]=p[find(y)];
}
kruskal();
}
return 0;
}