题目描述
输入
输出
示例输入
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));
     }
 }