次小生成樹(Prim)
阿新 • • 發佈:2018-11-19
這裡的思路就是先用prim演算法求的最小生成樹,然後在prim演算法中新增一個MAX陣列,用MAX陣列存放兩點間的最大距離,並且用一個use陣列(布林型別)存放是否使用過該邊,最後再在沒有使用的變進行遍歷,找出最小,求的最小生成樹!
引用:
下面介紹一下利用prim求次小生成樹的主要步驟。
1.先求出來最小生成樹。並將最小生成樹任意兩點之間路徑當中的權值最大的那一條找出來,為什麼要找最大的呢,因為生成樹加入一條邊之後一定構成了迴路,那麼肯定要去掉這個迴路當中一條邊才是生成樹,那麼,怎麼去邊才是次小的,那就去掉除了剛剛新增的一條邊之外迴路當中權值最大的一個,所以留下的就是最小的。
2.列舉最小生成樹外的每一條邊。找出最小的就是次小生成樹。
const int MAXN = 110; const int INF = 0x3f3f3f3f; bool vis[MAXN]; int low[MAXN]; int pre[MAXN]; int MAX[MAXN][MAXN]; bool used[MAXN][MAXN]; int cost[MAXN][MAXN]; int Prime(int n){ int ans=0; memset(vis,false,sizeof vis); memset(low,0,sizeof low); memset (MAX,0,sizeof MAX); memset(used,false,sizeof used); memset(low ,0 ,sizeof low); pre[0]=-1; vis[0]=true; low[0]=0; for(int i=0;i<n;i++) low[i]=cost[0][i]; for(int i=1;i<n;i++){ int minc=INF; int p=-1; for(int j=1;j<n;j++){ if(!vis[j]&&minc>low[j]){ p=j; minc=j; } } if(p==-1) return -1; ans+=minc; vis[p]=true; used[pre[p]][p]=used[p][pre[p]]=true; for(int j=1;j<n;j++){ if(vis[j]) MAX[j][p]=MAX[p][j]=max(MAX[j][pre[p]],low[p]); if(!vis[j]&&low[j]>cost[p][j]){ low[j]=cost[p][j]; pre[j]=p; } } } return ans; }
貼上一個例題
https://vjudge.net/problem/OpenJ_Bailian-1679
程式碼明天發