丟兩個模板...都是建立在最小生成樹的基礎上。
如果對最小生成樹還不是很了解的話,可以戳這裡
目錄
一、prim演算法(複雜度n^2+e)
二、kruskal演算法(複雜度n^2log(n+m) + n*m)
演算法過程:
先求最小生成樹t,列舉新增不在t中的邊,則新增後一定會形成環,找到環上除了新加入的邊的其餘邊權的最大值,把它刪掉,計算當前生成樹的權值,取所有列舉修改的生成樹的最小值,即為次小生成樹。
#include#include#includeusing namespace std;
const int maxn=110;
const int inf=0x3f3f3f3f;
int n,m;
int edge[maxn][maxn];
int max[maxn][maxn];
bool used[maxn][maxn],vis[maxn];//判斷這條邊是否加入最小生成樹中
int pre[maxn];//記錄前驅結點
int dis[maxn];//表示i與當前生成樹中的點有連邊的邊長最小值
int prim()//計算最小生成樹
pre[1]=0;
dis[1]=0;
vis[1]=true;
for(int i=2;i<=n;i++)}}
return ans;
}int check(int min_ans)//計算最小生成樹
}if(ans==inf)return -1;
return ans;
}int main()
int ans=prim();
if(ans==-1)
if(check(ans)==ans)
printf("not unique!\n");
else printf("%d\n",ans);
}return 0;
}
【模板題】poj1679 the unique mst
用並查集連線邊時標記在最小生成樹中的邊,求出最小生成樹。再遍歷一遍所有邊,將之前標記過的的邊刪去再求最小生成樹,取這些值中的最小值即是次小生成樹。
#includeusing namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
int n,m,pre[maxn],ans=0;
struct node
node[maxn];
bool cmp(node a,node b)
int findroot(int x)
int kruskal(int t)
if(k==n-1)return 1;
}return 0;
}int main()
sort(node+1,node+m+1,cmp);
int ans;
if(kruskal(1))ans=ans;
int minn=inf;
for(int i=1;i<=m;i++)
}printf("%d\n",minn);
}
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
次小生成樹
演算法引入 設g v,e,w 是連通的無向圖,t是圖g的一棵最小生成樹 如果有另一棵樹t1,滿足不存在樹t t t1 則稱t1是圖g的次小生成樹 演算法思想 鄰集的概念 由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n t 設t是圖g的最小生成樹,如果t1滿足 t1 min,...
次小生成樹
分類 圖論 2013 02 12 15 03 32人閱讀收藏 舉報次小生成樹 在求最小生成樹時,用陣列path i j 來表示mst中i到j最大邊權。求完後,直接列舉所有不在mst中的邊,把它加入到mst中構成一棵新的樹,且該樹有環,此環是由剛加入的邊 i,j 造成的,所以可以通過刪除path i ...