Agri-Net 最短網路
阿新 • • 發佈:2019-01-27
農民約翰被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起網際網路,並連線到所有的農場。當然,他需要你的幫助。 約翰已經給他的農場安排了一條高速的網路線路,他想把這條線路共享給其他農場。為了用最小的消費,他想鋪設最短的光纖去連線所有的農場。 你將得到一份各農場之間連線費用的列表,你必須找出能連線所有農場並所用光纖最短的方案。
Input
第一行: 農場的個數,N(3<=N<=100)。 第二行..結尾: 後來的行包含了一個N*N的矩陣,表示每個農場之間的距離。理論上,他們是N行,每行由N個用空格分隔的陣列成,實際上,他們限制在80個字元,因此,某些行會緊接著另一些行。當然,對角線將會是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
kruskal 演算法求解,(可能用prim會快一點,先佔個坑)
開始時
#define N 105 寫成了 #define N 100 + 5,還竟然是wrong answer?
#include <map> #include <set> #include <cmath> #include <stack> #include <cstdio> #include <vector> #include <utility> #include <cstring> #include <iostream> #include <algorithm> #define eps 1e-8 #define PI acos(-1) #define INF 0x3f3f3f3f #define N 105 #define newmax(a,b) a>b?a:b #define newmin(a,b) a>b?b:a #define Lowbit(x) (x&-x) using namespace std; typedef long long int LL; const int dir[4][2]= { {1,0},{0,1},{-1,0},{0,-1} }; struct Edge { int s,e,v; }edge[N*(N-1)/2]; int n,m; int parent[N]; int cmp(struct Edge a,struct Edge b) { return a.v<b.v; } void verset() { for(int i=1;i<=n;i++) parent[i]=-1; } int Find(int x) { int s; for(s=x;parent[s]>0;s=parent[s]); while(s!=x) { int temp=parent[x]; parent[x]=s; x=temp; } return s; } void Union(int R1,int R2) { int r1=Find(R1),r2=Find(R2); int temp=parent[r1]+parent[r2]; if(parent[r2]<parent[r1]) { parent[r1]=r2; parent[r2]=temp; } else{ parent[r2]=r1; parent[r1]=temp; } } void Kruskal() { int sum=0; int num=0; verset(); for(int i=0;i<m;i++) { int u=edge[i].s,v=edge[i].e; if(Find(u)!=Find(v)) { Union(u,v); num++; sum+=edge[i].v; } if(num>=n-1) break; } printf("%d\n",sum); } int main() { int g=0; scanf("%d",&n); m=n*(n-1)/2; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int t; scanf("%d",&t); if(i<j) { edge[g].v=t; edge[g].s=i; edge[g].e=j; g++; } } } sort(edge,edge+g,cmp); Kruskal(); return 0; }