#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define M 105
//int mat[M][M];
/*int pre[M];
int Find(int x)
{
int p,t;
p=x;
while(x!=pre[x])
x=pre[x];
while(p!=x)
{
t=pre[p];
pre[p]=x;
p=t;
}
return x;
}
bool join(int a,int b)
{
a=Find(a);
b=Find(b);
if(a==b)
{
return false;
}
else
{
pre[b]=a;
return true;
}
}*/
int prim(int n,int sta,int mat [][M])//n表示有n个顶点,sta表示从sta这个顶点出发生成最小生成树
{
int mark[M],dis[M];
int i,j,sum = 0,flag; //sum是总的最小生成树边权值
for (i = 0; i < n; i ++) //初始化dis[i] 表从顶点sta到点i的权值
{
dis[i] = mat[sta][i];
mark[i] = 0;
}
mark[sta] = 1; //sta 这个顶点加入最小生成树中
for (i = 1; i < n; i ++) //循环n-1次,每次找出一条最小权值的边 n个点的图
{
//只有n-1条边
int min = inf; //inf 表无穷大
for (j = 0; j < n; j ++) //找出当前未在最小生成树中边权最小的顶点
if (!mark[j] && dis[j] < min)
min = dis[j],flag = j;
if(min==inf)
return 0;
mark[flag] = 1; //把该顶点加入最小生成树中
sum += dis[flag]; //sum加上其边权值
for (j = 0; j < n; j ++) //以flag为起点更新到各点是最小权值
if (dis[j] > mat[flag][j])
dis[j] = mat[flag][j];
}
return sum; //返回边权总和
}
int main()
{
int n,m;
while(cin>>n>>m&&n)
{
int mat[M][M];
/*for(int i=0;i<M;i++)
pre[i]=i;*/
memset(mat,inf,sizeof(mat));
int t=1;
for(int i=0; i<n; i++)
{
int a,b,c;
cin>>a>>b>>c;
mat[a-1][b-1]=mat[b-1][a-1]=c;
/* if(!join(a-1,b-1))
{
t++;
}*/
}
//int t=pre[0];
/*for(int i=0; i<m; i++)
{
if(t<m-1)
{
cout<<"?"<<endl;
flag=1;
break;
}
}
if(!flag)*/
int ca=prim(m,0,mat);
if(ca)
cout<<ca<<endl;
else
cout<<"?"<<endl;
}
}
prim算法(不用并查集)
转载于:https://www.cnblogs.com/dillydally/p/9567804.html