USACO 3.1.1 Agri-Net 最短网络(最小生成树Prime算法)

所谓最小生成树就是给定一个无向图G = (V, E) 中,G是无向图中所有顶点和边的集合,(u, v) 代表连接顶点 u 与顶点 v 的边,而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集且为无循环图,使得 w(T) 最小,则此 T 为 G 的最小生成树

而Prime算法就是在无向图中来寻找这样一颗最小生成树。

思想:

1 先选取第一个顶点,然后找出第一个顶点到其他顶点的最小值,然后标记最小值的路径已走过,加入该顶点;2计算现有顶点到其他顶点的最小值,更新最小值列表,找出最小值列表中的最小值,标记路径,加入顶点;3重复以上过程,直到所有顶点都加入;

这个题目就是赤裸裸的Prime算法。以题目中给出的样例来模拟程序执行的过程:

USACO 3.1.1 Agri-Net 最短网络(最小生成树Prime算法)_第1张图片

如图所示:先选取1顶点,1顶点到各顶点的最小距离为dis[2]=4,dis[3]=9,dis[4]=21,最小值为4,所以第二个顶点选取顶点2加入,顶点2到顶点3的距离为8<顶点1到顶点3的距离9,所以把9替换为8,即dis[3]=8,同样可替换dis[4]=17,这样下一个加入的顶点为3,然后顶点3到顶点4的距离为16<顶点2到顶点4的距离17,所以dis[4]=16。即为一下过程:

USACO 3.1.1 Agri-Net 最短网络(最小生成树Prime算法)_第2张图片

代码如下:

/*
ID: supersnow0622
PROG: agrinet
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include<memory.h>
using namespace std;
int visit[101],mindis[101];
int data[101][101];
int prime(int cost[][101],int num)
{
   int min,node,sum=0;
   memset(visit,0,sizeof(visit));
       visit[0]=1;
    for(int i=0;i<num;i++)
     mindis[i]=cost[0][i];
    for(int i=1;i<num;i++)
    {
       min=10000000;
       node=-1;
       for(int j=1;j<num;j++)
         if(visit[j]==0&&mindis[j]<min)
          {
             min=mindis[j];
             node=j;
          }
   //     if(min==10000000)return -1;
       visit[node]=1;
       sum+=min;
       for(int j=1;j<num;j++)
         if(visit[j]==0&&mindis[j]>cost[node][j])
            mindis[j]=cost[node][j];
    }
   return sum;
}
 
int main() {
    ofstream fout ("agrinet.out");
    ifstream fin ("agrinet.in");
    int N;
    cin>>N;
    for(int i=0;i<N;i++)
     for(int j=0;j<N;j++)
       cin>>data[i][j];
    cout<<prime(data,N);
    return 0;
}
 








你可能感兴趣的:(USACO 3.1.1 Agri-Net 最短网络(最小生成树Prime算法))