最小生成树(prim算法) -- 路路通注释版

数据结构实验之图论六:村村通公路

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic Discuss

Problem Description

当前农村公路建设正如火如荼的展开,某乡镇政府决定实现村村通公路,工程师现有各个村落之间的原始道路统计数据表,表中列出了各村之间可以建设公路的若干条道路的成本,你的任务是根据给出的数据表,求使得每个村都有公路连通所需要的最低成本。

Input

连续多组数据输入,每组数据包括村落数目N(N <= 1000)和可供选择的道路数目M(M <= 3000),随后M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个村庄的编号和修建该道路的预算成本,村庄从1~N编号。 

Output

输出使每个村庄都有公路连通所需要的最低成本,如果输入数据不能使所有村庄畅通,则输出-1,表示有些村庄之间没有路连通。 

Sample Input

5 8
1 2 12
1 3 9
1 4 11
1 5 3
2 3 6
2 4 9
3 4 4
4 5 6

Sample Output

19
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
int map[105][105];  //邻接矩阵
int vis[105];       //记录该城市是否已经经过
int dist[105];      //记录其他相邻城市到这个城市的最短距离  
void prim(int m)    //村庄的数量
{
    int i, j, k, u, min, ans = 0;
    for(i = 1;i <= m;i++)
    { //从1开始,将该城市与其他城市的值更新给dist
        dist[i] = map[1][i];
    }
    vis[1] = 1;  //标记经过的城市
    for(i = 2;i <= m;i++) //m-1次
    {
        min = INF;  //初始化min为无穷大
        for(j = 1;j <= m;j++)
        {   //找到已经标记vis的点,到j城市最小的路径
            if(min > dist[j] && !vis[j])
            {
                min = dist[j];//更新min
                u = j;//标记该城市
            }
        }
        if(min == INF)break;//代表路不连通,跳出循环
        vis[u] = 1;//标记使用过的城市
        ans = ans + min;//求和
        for(k = 1;k <= m;k++)
        {   //给正要经过的城市更新一下总共需要的花费
            if(!vis[k] && dist[k] > map[u][k])
                dist[k] = map[u][k];//更新dist的值
        }
    }
    if(i == m + 1)printf("%d\n",ans);//按要求输出ans
    else printf("?\n");
}
int main()
{
    int m, n, i, j, u, v, w;
    while(~scanf("%d %d",&n,&m))
    {
        memset(map,INF,sizeof(map));
        memset(vis, 0, sizeof(vis));//初始化vis为0
        for(i = 1; i <= n;i++)
        {
           map[i][i] =  0;        //除了其自身,权值全为无穷大
        }
        for(i = 1;i <= m;i++)
        {
            scanf("%d %d %d",&u,&v,&w);//城市与城市之间的距离
            if(map[u][v] > w)
            {
                map[u][v] = map[v][u] = w;
            }
        }
        prim(n);//调用prim
    }
    return 0;
}

prim模板:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int map[105][105];
int vis[105];
int dist[105];
void Prim(int m)
{
   int i, j ,k, min, ans = 0;
   for(i = 1;i <= m;i++)
   {
       dist[i] = map[1][i];
   }
   vis[1] = 1;
   for(i = 2;i <= m;i++)
   {
       min = INF;
       for(j = 1;j <= m;j++)
       {
           if(!vis[j] && min > dist[j])
           {
               min = dist[j];
               u = j;
           }
       }
       if(min == INF)break;
       vis[u] = 1;
       ans = ans + min;
       for(j = 1;j <= m;j++)
       {
           if(!vis[j] && dist[j] > map[u][j])
           {
               dist[j] = map[u][v];
           }
       }
   }
   if(i == m + 1)printf("%d\n",ans);
   else printf("-1\n");
}

猜你喜欢

转载自blog.csdn.net/weixin_40616644/article/details/82012298