演算法學習之路|最小生成樹——prime演算法

kissjz發表於2018-02-28

演算法概述:對於一個帶權的連通圖,其頂點的集合 為V,邊的集合為E。定義一個新的集合Vnew={空},第一步在圖中任選一個頂點v加入Vnew,第二步尋找最短的邊(u,v),其中u∈Vnew,v∈V-Vnew,其中v加入Vnew,迴圈執行第二步直到Vnew=V結束。

void prime()
{
  int i,j;
  int min=INF;
  for(i=1;i<n+1;i++)
      lowcost[i]=INF;
  int vnew[N+1]={0};
  for(i=1;i<n;i++)
  {
      int k;
      min=INF;
      for(j=1;j<=n;j++)
      { 
          if(!vnew[j]&&min>lowcost[j])
          {
              min=lowcost[j];
              k=j;
          }
      }
      vnew[k]=1;
      for(j=1;j<=n;i++)
      {
          if(!vnew[j]&&map[k][j]<lowcost[j])
          {
              lowcost[j]=map[k][j];
          }
      }
  }
}

題目大意:n個城市,知道各個城市的距離,建路將n個城市互相可達,路是直線建的,max=各個城市最長的那條路,求所有建路方案中max的最小值。

解題思路:直接prime求最小生成樹

程式碼(已ac)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 510
#define INF 0x3f3f3f3f
using namespace std;
int _map[N][N];
int Vnew[N];
int lowcost[N];
int prime(int n)
{
    int i,j;
    int _min;
    int ans=-1;
    for(i=1;i<=n;i++)
        lowcost[i]=INF;
    lowcost[1]=0;
    memset(Vnew,0,sizeof(Vnew));
    for(i=1;i<=n;i++)
    {
        int k;
        _min=INF;
        for(j=1;j<=n;j++) 
        { 
            if(!Vnew[j]&&_min>lowcost[j])
            {
                _min=lowcost[j];
                k=j;
            }
        }
        ans=max(ans,_min);
        Vnew[k]=1;
        for(j=1;j<=n;j++) 
        { 
            if(!Vnew[j]&&lowcost[j]>_map[k][j])
            {
                lowcost[j]=_map[k][j];
            }
        }
    }
    return ans;
}

int main (void)
{
    int T,i,j;
    int k;
    scanf("%d",&T);
    int n;
    while(T--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                scanf("%d",&_map[i][j]);
        k=prime(n);
        printf("%d
",k);
    }
    return 0;
}

 


相關文章