1. 程式人生 > >WUST 1944 最短網路Agri-Net(最小生成樹之prim演算法)

WUST 1944 最短網路Agri-Net(最小生成樹之prim演算法)

1944: 最短網路Agri-Net

Time Limit: 1 Sec  Memory Limit: 128 MB  64bit IO Format: %lld
Submitted: 22  Accepted: 9
[Submit][Status][Web Board]

Description

  農民約翰被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起網際網路,並連線到所有的農場。當然,他需要你的幫助。約翰已經給他的農場安排了一條高速的網路線路,他想把這條線路共享給其他農場。為了用最小的消費,他想鋪設最短的光纖去連線所有的農場。你將得到一份各農場之間連線費用的列表,你必須找出能連線所有農場並所用光纖最短的方案。每兩個農場間的距離不會超過100000。

Input

多組測試資料。 第一行:農場的個數,N(3<=N<=100)。 後來的行包含了一個N*N的矩陣,表示每個農場之間的距離。N行,每行由N個用空格分隔的陣列成。 當然,對角線將會是0,因為不會有線路從第i個農場到它本身。

Output

只有一個輸出,其中包含連線到每個農場的光纖的最小長度。

Sample Input 

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

Sample Output

28


題解:

比較水,看到給了鄰接矩陣就想到用prim演算法,算是prim演算法練練手,就是隨便找個點作為起始點,然後加入全家桶套餐,vis標記為1,遍歷這個點所有另一端沒加入全家桶套餐的邊,加入優先佇列(值小的先出),然後取出另一端沒加入套餐且最小值的邊,另一個點加入全家桶套餐,然後和剛才一樣迴圈。。知道找完所有的點

程式碼:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<string>
#include<stdio.h>
#include<queue>
#include<stack>
#include<map>
#include<deque>
using namespace std;
const int INF=100861111;
int vis[105];
struct edge
{
    int to;//該邊通向的地方
    int v;//邊的值
    friend bool operator<(edge x,edge y)//優先佇列過載小於號,值小的點pop
    {
        return x.v>y.v;
    }
};
priority_queue<edge>q;
int p[105][105];
int main()
{
    int i,j,k,n,m,ans,s;
    edge now;
    while(scanf("%d",&n)!=EOF)
    {
        s=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%d",&p[i][j]);
            }
            vis[i]=0;//初始化
        }
        while(!q.empty())q.pop();
        int key=0;
        ans=1;
        vis[0]=1;
        while(ans<n)//早足了點就退
        {
            for(i=0;i<n;i++)
            {
                if(!vis[i])
                {
                    now.to=i;
                    now.v=p[key][i];
                    q.push(now);
                }
            }
            while(!q.empty()&&vis[q.top().to])q.pop();//把已經加入全家桶套餐的邊pop掉
            now=q.top();
            s+=now.v;
            ans++;
            key=now.to;
            vis[key]=1;
        }
        printf("%d\n",s);
    }
    return 0;
}