最小度限制生成樹是指某乙個節點的度限制為k的最小生成樹。具體的做法去看**或者黑書吧,這裡不詳細講了。
理解最小度限制生成樹的解法,最主要的就是看懂如何由m度生成樹求m+1度生成樹,另外要理解無解的情況。
今天終於把模板整理出來了,prim那裡用了優先佇列優化,新增刪除邊破環那裡用的是動態規劃。試了試pku1639這道題,結果正確,但是由於資料水,不知道效率如何。
貼出模板:
1#define maxn 505
2struct
str3
edge[maxn<<1];//
鄰接表6
inthead[maxn],cnt;
7void
init()812
void addedge(int u,int v,int
c)13
23int
dis[maxn],best[maxn],index[maxn];
24//
dis是prim裡到某節點的最短距離,best具體含義看**,index是best對應的邊號
25int incom[maxn],com;//
記錄節點在哪個聯通分量裡
26bool vis[maxn],intree[maxn<<1
];27
struct
node
2831 node(int _u,int _c,int
_e):u(_u),c(_c),e(_e){}
32bool
operator
<(const node a)const
33 };//
優先佇列資料結構
34 priority_queueq;
35int prim(int n,int
s)3656}
57}58 memset(vis,0,sizeof(vis));//
vis陣列復用,判斷某節點所在的連通分量是否已經連線
59for(int i=head[s];i!=-1;i=edge[i].n)
6064
while(!q.empty())//
把各個分量連起來,這樣就求出m度最小生成樹
6571
return
val;72}
73void dfs(int u,int fa,int n,int s)//
更新best
7485
dfs(v,u,n,s);86}
87}88//
int mval;
89int klimit(int n,int s,int k)//
求k度最小生成樹,n是節點個數,s是度被限制的節點,k為限制的度數
90103
if(ed==-1)return inf;//
無法再使度擴大則也是無解的
104int v=edge[ed].v,dx=index[v];
105 val+=mn;
106//
mval=min(val,mval);
107 intree[ed]=intree[ed^1]=true
;108 intree[dx]=intree[dx^1]=false
;109 best[v]=-inf,dfs(v,s,n,s);
110}
111return
val;
112 }
如果是求某節點正好為k度則就是上面的模板,如果節點的度不大於k則將上面mval的三條注釋取消掉,最後結果就是mval。
最小度限制生成樹
最小度限制生成樹 具體講解和證明,黑書上有,ioi2004國家集訓隊 王汀 中也有講解,這裡簡單介紹求法過程。為了方便敘述,把頂點v0的度數 k稱作度限制條件,把滿足這一條件的生成樹稱為度限制生成樹,把權值和最小的度限制生成樹稱為最小度限制生成樹。要求的最小k度生成樹,應該有以下的步驟 演算法框架 ...
最小度限制生成樹
在一棵生成樹中,某個頂點v0的度數 k稱作度限制條件,把滿足這一條件的生成樹稱為度限制生成樹,把權值和最小的度限制生成樹稱為最小度限制生成樹。如果撇開度限制條件,那麼就是最小生成樹問題。首先,避開度限制條件。假如把最小度限制生成樹中所有與v0相關的邊都刪掉,得到m個連通分量。具體步驟 1.如果k 2...
最小度限制生成樹
黑書 各種資料。終於理解了一點。最小度限制生成樹就是給乙個圖,讓求它的最小生成樹。找的的最小生成樹滿足並且點vo的度最大為k。演算法流程如下 1.將該點 以下用v0表示 從圖中刪除,將得到m個連通分量。2.對每個連通分量求最小生成樹,假設m個。3.從每個連通分量中找與v0關聯的權值最小的邊,與v0相...