题目描述
输入
输出
示例输入
3 2
1 2 1
1 3 1
1 0
示例输出
2
0
提示
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
int arr[110][110];//记录顶点之间的弧关系;
int dis[110];//用来记录当前生成树到每个节点的距离(权值);
bool vis[110];//标记数组
int prim(int n)//生成最小树,求最小权值;
{
memset(vis,false,sizeof(vis));//标记数组清零
for(int i=1;i<=n;i++)
dis[i]=arr[1][i];;//从1号节点开始生成树
int ans=0;//距离权值总和
vis[1]=true;//生成树的根(起点)标记访问过
for(int i=2;i<=n;i++)//要生成n-1条边,所以循环n-1次
{
int pos=i;//用来记录每一次循环找到的结点编号
int min=INF;;//标记为无穷大
for(int j=1;j<=n;j++)//对dis数组进行遍历找到距离最小的
if(vis[j]==false&&dis[j]<min)
{
min=dis[j];//更新最小距离
pos=j;//记录节点编号
}
ans+=min;//加上找到的最小权值
vis[pos]=true;//标记找到的该点被访问
for(int j=1;j<=n;j++)//更新dis数组
if(vis[j]==false&&dis[j]>arr[pos][j])//路径通过中间路径pos使路径更小。
dis[j]=arr[pos][j];//更新生成树到该点的距离
}
return ans;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)//边的初始化;
{
if(i==j)
arr[i][j]=0;
else
arr[i][j]=INF;//无穷大;
}
for(int i=1,v1,v2,w;i<=m;i++)
{
scanf("%d%d%d",&v1,&v2,&w);
if(arr[v1][v2]>w||arr[v2][v1]>w)//选取权值最小的边;
arr[v1][v2]=arr[v2][v1]=w;
}
printf("%d\n",prim(n));
}
}