判斷最小生成樹是否唯一,求次小生成樹。
原理首先求得最小生樹,然後列舉沒有在最小生成樹上的邊,加上這個邊之後樹上必定成環,刪除環上除剛加入邊的最長邊,就得到乙個新的生成樹。
實現演算法的關鍵是記錄兩點在最小生成樹上的最大距離
// kruskal
int n, m;
struct ac
}g[maxn*maxn]
;vector<
int> son[maxn]
;int pre[maxn]
, dis[maxn]
[maxn]
;int find (
int x)
void
kruskal()
sort
(g, g+m)
;int sum =0;
int cnt =0;
for(
int i =
0; i < m;
++i)
// 更新兩點的距離最大值
for(
int j =
0; j < lenx;
++j)
} pre[fy]
= fx;
//合併子樹
for(
int j =
0; j < leny;
++j)
son[fy]
.clear()
;}int ans = inf;
for(
int i =
0; i < m;
++i)
printf
("%d %d\n"
, sum, ans)
;}
// prim
int n, m;
int g[maxn]
[maxn]
, val[maxn]
, vis[maxn]
, dis[maxn]
;int pre[maxn]
, maxd[maxn]
[maxn]
;bool used[maxn]
[maxn]
;void
prim
(int s)
vis[s]=1
;int sum =
0, cnt =0;
for(
int i =
1; i < n;
++i)}if
(u ==-1
)break
; vis[u]=1
; sum +
= min;
cnt++
; used[pre[u]
][u]
= used[u]
[pre[u]]=
1;maxd[u]
[pre[u]
]= maxd[pre[u]
][u]
= min;
for(
int j =
1; j <= n;
++j)
if(vis[j]==0
&& dis[j]
> g[u]
[j])}}
if(cnt != n-1)
int ans = inf;
for(
int i =
1; i <= n;
++i)
}printf
("%d %d\n"
, sum, ans)
;}
板子題
poj 1679
accode
hdu 4081
accode
uva 10600
accode
uva 10462
accode
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 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 ...