WUST 1944 最短網路Agri-Net(最小生成樹之prim演算法)
阿新 • • 發佈:2019-02-10
1944: 最短網路Agri-Net
Time Limit: 1 Sec Memory Limit: 128 MB 64bit IO Format: %lldSubmitted: 22 Accepted: 9
[Submit][Status][Web Board]
Description
農民約翰被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起網際網路,並連線到所有的農場。當然,他需要你的幫助。約翰已經給他的農場安排了一條高速的網路線路,他想把這條線路共享給其他農場。為了用最小的消費,他想鋪設最短的光纖去連線所有的農場。你將得到一份各農場之間連線費用的列表,你必須找出能連線所有農場並所用光纖最短的方案。每兩個農場間的距離不會超過100000。Input
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; }