http://acm.nyist.net/JudgeOnline/problem.php?pid=502
//并查集and最小生成树prim算法
#include<stdio.h>
#include<string.h>
#define MAX 0x3f3f3f
#define N 110
int graph[N][N];
int visited[N],ps[N];
int a[N];
int find(int k) //并查集
{
int r=k;
while(a[r]!=r)
r=a[r];
int y=k,tem;
while(y!=r) //路径压缩
{
tem=a[y];
a[y]=r;
y=tem;
}
return r;
}
int cmp(int m) //prim 算法
{
int i,j,pos,min,sum=0;
memset(visited,0,sizeof(visited));
pos=1;
visited[1]=1;
for(i=2;i<=m;i++)
ps[i]=graph[pos][i];
for(i=1;i<m;i++)
{
min=MAX;
for(j=1;j<=m;j++)
{
if(!visited[j]&&ps[j]<min)
{
min=ps[j];
pos=j;
}
}
sum+=min;
visited[pos]=1; //进行标记
for(j=1;j<=m;j++)
if(!visited[j]&&graph[pos][j]<ps[j])//更新权值
ps[j]=graph[pos][j];
}
printf("%d\n",sum);
return 0;
}
int main()
{
int T,n,m,i,j;
int x,y,money;
int t1,t2,s;
scanf("%d",&T);
while(T--)
{
s=0;
memset(graph,MAX,sizeof(graph));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
a[i]=i;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&money);
graph[x][y]=graph[y][x]=money;
t1=find(x);
t2=find(y);
if(t1!=t2)
a[t1]=t2;
}
for(i=1;i<=m;i++)
if(a[i]==i)
s++;
if(s>=2)
{
printf("No solution\n");
continue;
}
cmp(m);
}
return 0;
}