次小生成樹,由最小生成樹替換一條邊得到
在生成最小生成樹的時候,用max[i][j]來記錄從i到j的路中(這條路是唯一的)值最大的那部分,如4>1->2>3,max[4][3]記錄的是4、1和1、3和2、3中值最大的那條,為什麼要這樣記錄呢,因為求次小生成樹的時候就是列舉圖的任意兩個點:
ans =
min(ans, min_ans +
map[i][j] -
max[i][j]);
ans是次小生成樹的路徑和,min_ans是最小生成樹的路徑和,map[i][j]是i,j中一條不在最小生成樹的邊(map[i][j]是要一條條列舉的),要使ans盡量小,那max[i][j]就要盡量大了,當邊替換的時候會生成乙個環,此時從最小生成樹中去掉一條邊即可,去的就是
max[i][j]。
**來自:
poj1679 the unique mst
題意:給定圖,讓求它的最小生成樹是否唯一。如果唯一的話輸出最小生成樹的權值和,否則輸出not unique!
思路:直接求次小生成樹就行。
#include
#include
#include
using
namespace
std;
const
intmaxn =
111;
const
intinf =
0x3f3f3f3f;
intmap[maxn][maxn];
//鄰接矩陣存圖
intmax[maxn][maxn];
//表示最小生成樹中i到
j的最大邊權
bool
used[maxn][maxn];
//判斷該邊是否加入最小生成樹
intpre[maxn];
intdis[maxn];
void
init(
intn)
void
read(
intm)
} intprim(
intn)
pre[
1] = 0;
dis[
1] = 0;
vis[
1] =
true;
for(
inti =
2; i <= n; i++)
} if(min_dis ==
inf)
return-1
;//如果不存在最小生成樹
ans += min_dis;
vis[k] =
true;
used
[k][
pre[k]] =
used
[pre
[k]][k] =
true;
for(
intj =
1; j <= n; j++)
} }
return
ans;
//最小生成樹的權值之和 }
intsmst(
intn,
intmin_ans)
//min_ans
是最小生成樹的權值和
void
solve(
intn)
if(smst
(n, ans) == ans)
printf
("not unique!\n");
else
printf
("%d\n"
, ans); }
intmain()
return0;
}
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 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 ...