最小度限制生成樹
具體講解和證明,黑書上有,ioi2004國家集訓隊**--王汀 中也有講解, 這裡簡單介紹求法過程。
為了方便敘述,把頂點v0的度數<=k稱作度限制條件,把滿足這一條件的生成樹稱為度限制生成樹,把權值和最小的度限制生成樹稱為最小度限制生成樹。
要求的最小k度生成樹,應該有以下的步驟:
演算法框架:
1. 先求出最小m度限制生成樹;
2. 由最小m度限制生成樹得到最小m+1度限制生成樹;
3. 當dt(v0)=k時停止(即當v0的度為k的時候停止);
部分引用**:
第一步求解最小m度限制生成樹:原圖中去掉和v0相連的所有邊,得到m個連通分量,而這m 個連通分量必須通過v0來連線,所以,在圖g 的所有生成樹中dt(v0)≥m。也就是說,當k第二步,由最小m度限制生成樹,得到最小m+1度限制生成樹,對於和v0相鄰的點v,則可以知道一定會有乙個環出現,只要找到這個環上的最大權邊,用邊(v0, v)替換掉,就可以得到乙個m+1度限制生成樹,列舉所有和v0相鄰點v,找到替換後增加權值最小的一次替換,就可以求得m+1度限制生成樹。。如果每新增一條邊,都需要對環上的邊一一枚
舉,時間複雜度將比較高,這裡,動態規劃就有了用武之地。設best(v)為路徑v0—v上與v0無關聯且權值最大的邊。定義father(v)為v的父結點,動態轉移方程:best(v)=max(best(father(v)),ω(father(v),v)),邊界條件為best[v0]=-∞,best[v』]=-∞| (v0,v』)∈e(t)。
第三步, 當度為k的時候就可以退出了。
pku1639 picnic planning 野餐計畫
這裡就是乙個度限制生成樹的應用,聚集地點最多能放k輛轎車,把聚集地點park 作為度限制點,就可以求所有小於等於k的度限制生成樹,取他們中最小值,即為這題的解。
1#include
<
stdio.h
>
2#include
<
string
.h>
3#define
nn 30
4#define
inf 0x3fffffff
5int
idx, s;
//s為需要限制度的那一點
6int
k, mst;
//k表示k度限制,mst為最後的結果
7int
pre[nn];
8int
mark[nn];
9int
dis[nn];
10int
vis[nn];
11char
str[nn][nn];
12int
map[nn][nn];
13int
best[nn];
//存的是最大權值邊的終點
14int
edg[nn][nn];
//edg[i][j] = 1 表示邊[i,j]已在生成樹中
15int
father[nn];
//生成樹中的父節點
1617
intfind(
char
s)22
return-1
;23}24
25void
dfs(
intcur)33}
34}3536
intprim(
ints)
44memset(mark, 0,
sizeof
(mark));
45mark[s] =1
;46vis[s] =1
;4748while(1
)56}57
if(key ==-
1) break;58
mark[key] =1
; 59
vis[key] =1
;60edg[pre[key]][key]
=edg[key][pre[key]] =1
;61sum
+=dis[key];
62for
(i =
0; i
<
idx; i++)
67}68}
69min
=inf;
70int
root =-
1; //樹根
71for
(i =
0; i
<
idx; i++)
76}77//
拉成有根樹
78mark[root] =0
;79dfs(root);
80father[root] =s;
81return
sum
+min;82}
8384
intbest(
intx)
90tmp
=best(father[x]);
91if
(tmp !=-
1&&map[tmp][father[tmp]]
>
map[father[x]][x])
else
best[x] =x;
94return
best[x];95}
9697
void
solve()
98111
}112
/*for (i = 0; i < idx; i++)可以用於除錯錯誤
115*/
116int
minadd, ax, bx,tmp;
117int
change;
//回路上權值最大的邊,用於交換
118for
(i =m +
1; i
<=
k &&
i <
idx; i++)
125}
126minadd
=inf;
//交換邊的最小差值
127for
(j =
0; j
<
idx; j++)
136}
137}
138if
(minadd
>=0)
break;//
用於度數不大於k的限制,如果k限制,就不用break了
139mst
+=minadd;
140ax
=best[change];
141bx
=father[ax];
142map[ax][bx]
=map[bx][ax]
=inf;
143father[ax]
=bx =s;
//改變生成樹,將點ax直接指向源點s
144map[ax][bx]
=map[bx][ax]
=map[change][s];
145map[s][change]
=map[change][s]
=inf;
146}
147}
148int
main()
149157
}158
idx =1
;159
strcpy(str[
0],
"park");
160while
(n--
)167y =
find(s2);
168if
(y ==-1
)172
if(d
<
map[x][y])
176}
177scanf("%d
", &k);
178s =0
;179
solve();
180printf(
"total miles driven: %d\n
", mst);
181return0;
182}
183
最小度限制生成樹
在一棵生成樹中,某個頂點v0的度數 k稱作度限制條件,把滿足這一條件的生成樹稱為度限制生成樹,把權值和最小的度限制生成樹稱為最小度限制生成樹。如果撇開度限制條件,那麼就是最小生成樹問題。首先,避開度限制條件。假如把最小度限制生成樹中所有與v0相關的邊都刪掉,得到m個連通分量。具體步驟 1.如果k 2...
最小度限制生成樹
黑書 各種資料。終於理解了一點。最小度限制生成樹就是給乙個圖,讓求它的最小生成樹。找的的最小生成樹滿足並且點vo的度最大為k。演算法流程如下 1.將該點 以下用v0表示 從圖中刪除,將得到m個連通分量。2.對每個連通分量求最小生成樹,假設m個。3.從每個連通分量中找與v0關聯的權值最小的邊,與v0相...
ACM 最小度限制生成樹
最小度限制生成樹是指某乙個節點的度限制為k的最小生成樹。具體的做法去看 或者黑書吧,這裡不詳細講了。理解最小度限制生成樹的解法,最主要的就是看懂如何由m度生成樹求m 1度生成樹,另外要理解無解的情況。今天終於把模板整理出來了,prim那裡用了優先佇列優化,新增刪除邊破環那裡用的是動態規劃。試了試pk...