最小度限制生成樹

2021-06-17 15:28:28 字數 4064 閱讀 5363

最小度限制生成樹

具體講解和證明,黑書上有,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...