題意就是求最小生成樹 但是有乙個頂點的度必須不大於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...