POJ 1639 k度限制生成樹

2021-08-27 01:13:46 字數 2310 閱讀 1754

題意就是求最小生成樹 但是有乙個頂點的度必須不大於k

具體的方法網上都有,但是**寫起來之複雜難以令人想象,我由於**能力還太弱,導致只能看著別人的**重寫一遍,優化了一些部分。

1.求出除去k度點的最小生成森林,設森林數為m

2.將這m棵樹與k度點用每棵樹中與k度點距離最短的點相連,生成乙個m度最小生成樹,總答案為這個生成樹的所有邊長之和

3.迭代k-m次,嘗試將m度生成樹擴充套件為k度生成樹,並求出最小生成樹的長度

(1)掃瞄k度點的所有鄰接點,(注意,這是掃瞄的原圖) 找到乙個點使得(新的生成樹中該點到k度點最大邊的長度)與(原圖中k度點到該點的距離)之差最大。 (注意,該點不能是生成樹中直接與k度點相連的點)

(2) 若(1)找出的差值不大於0,則無須繼續往下找,否則,在新的生成樹中連線該點到k度點,並將最大邊替換掉,然後從該點開始更新最大邊。此時,m度生成樹變為m+1度生成樹,總答案減去該差值。

(3)迴圈以上步驟,直到變為k度生成樹或者跳出

4.列印答案

#include #include #include #include #include #define maxn 105

#define maxm 100005

#define inf 1000000000

using namespace std;

struct node

edge[maxm];

struct edge

edge(int a, int b, int c)

void init()

bool operator >(const edge &a) const

}mx[maxn];//用於儲存每個點到park點的最大邊

int n, m, k, sum;//sum為結果

int e, head[maxn], vis[maxn], dis[maxn], use[maxn][maxn];//head用於鄰接表 vis是標記陣列 dis用於求最小生成樹

//use用來標記兩點之間是否有邊

int blocks, size[maxn], belong[maxn], nearvex[maxn];//blocks表示去除park後有幾個連通塊 size是每個連通塊的個數

//belong表示該點屬於哪個連通塊 nearvex用於在生成樹中記錄邊

int point[maxn], link[maxn]; //point表示每個連通塊中與park點最近的點 link則是該點與park點的距離

mapmp; //用於對映名字

void init()

void insert(int x, int y, int w)

int getid(char s)

void dfs(int v) //該dfs將圖分成了一些連通塊

void prim(int cur) //對某個連通塊求最小生成樹

for(int i = 1; i <= size[cur]; i++) //迴圈次數為該塊的頂點數,因為這與一般的求mst略微不同}}

}void getmax(int v, int fa, int w) //該函式用於更新新的生成樹中點到park點的最大邊

void ge***egreemst()

nearvex[1] = -1;

for(int i = 1; i <= blocks; i++) prim(i);

for(int i = 1; i <= n; i++) link[i] = inf;

for(int i = head[1]; i != -1; i = edge[i].next) //生成一棵m度的生成樹

if(link[belong[edge[i].v]] > edge[i].w)

for(int i = 1; i <= blocks; i++) //將park點與每個連通塊中與其最近的點相連,並且標記邊

}void slove()

if(!pos) break;

sum -= maxval;//更新答案

degree++;

use[mx[pos].u][mx[pos].v] = use[mx[pos].v][mx[pos].u] = 0;//將最大邊刪除

use[1][pos] = use[pos][1] = 1;

getmax(pos, 1, w);//更新最大邊

}}int main()

scanf("%d", &k);

ge***egreemst();

slove();

printf("total miles driven: %d\n", sum);

return 0;

}

poj1639頂點度限制生成樹

題目 對根的度數有限制的最小生成樹 先忽略根,跑最小生成樹,得到幾個連通塊,再一一與根連上 然後在限制內用根連出去的邊來使生成樹更小,這需要列舉邊以及用dp維護樹上邊的dfs序之前最大的乙個 此題用鄰接矩陣比較方便。改了一晚上,終於發現是混淆了n和cnt,cnt才是點數。鄰接表失敗版 include...

最小度限制生成樹

最小度限制生成樹 具體講解和證明,黑書上有,ioi2004國家集訓隊 王汀 中也有講解,這裡簡單介紹求法過程。為了方便敘述,把頂點v0的度數 k稱作度限制條件,把滿足這一條件的生成樹稱為度限制生成樹,把權值和最小的度限制生成樹稱為最小度限制生成樹。要求的最小k度生成樹,應該有以下的步驟 演算法框架 ...

最小度限制生成樹

在一棵生成樹中,某個頂點v0的度數 k稱作度限制條件,把滿足這一條件的生成樹稱為度限制生成樹,把權值和最小的度限制生成樹稱為最小度限制生成樹。如果撇開度限制條件,那麼就是最小生成樹問題。首先,避開度限制條件。假如把最小度限制生成樹中所有與v0相關的邊都刪掉,得到m個連通分量。具體步驟 1.如果k 2...