王室聯邦(bzoj 1086)

2022-05-14 05:56:07 字數 1489 閱讀 2158

「餘」人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成

員來管理。他的國家有n個城市,編號為1..n。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條

直接或間接的道路。為了防止管理太過分散,每個省至少要有b個城市,為了能有效的管理,每個省最多只有3b個

城市。每個省必須有乙個省會,這個省會可以位於省內,也可以在該省外。但是該省的任意乙個城市到達省會所經

過的道路上的城市(除了最後乙個城市,即該省省會)都必須屬於該省。乙個城市可以作為多個省的省會。聰明的

你快幫幫這個國王吧!

第一行包含兩個數n,b(1<=n<=1000, 1 <= b <= n)。接下來n-1行,每行描述一條邊,包含兩個數,即這

條邊連線的兩個城市的編號。

如果無法滿足國王的要求,輸出0。否則輸出數k,表示你給出的劃分方案中省的個數,編號為1..k。第二行輸

出n個數,第i個數表示編號為i的城市屬於的省的編號,第三行輸出k個數,表示這k個省的省會的城市編號,如果

有多種方案,你可以輸出任意一種。

8 2

1 2

2 3

1 8

8 7

8 6

4 6

6 5

3 2 1 1 3 3 3 3 2

2 1 8

/*

dfs一遍,如果某棵子樹的節點數》=b,那麼就割為乙個省,

此時這個省的節點數一定*/

#include

#include

#define n 1010

using

namespace

std;

intn,b,cnt,top,pro,q[n],head[n],size[n],belong[n],cap[n];

struct

node;node e[n*2

];void add(int i,int u,int

v)void dfs(int x,int

fa)

else size[x]+=size[e[i].v];

}size[x]++;

}void paint(int x,int fa,int

c)int

main()

for(int i=1;i)

dfs(

1,0);

if(!pro) cap[++pro]=1

; paint(

1,0,pro);

printf(

"%d\n

",pro);

for(int i=1;i<=n;i++)printf("

%d "

,belong[i]);

printf("\n

");for(int i=1;i<=pro;i++)printf("

%d "

,cap[i]);

return0;

}

bzoj1086 王室聯邦

給出一棵樹,求一種分塊方案,使得每個塊的大小 size in b,3b 每個塊還要選乙個省會,省會可以在塊外,但是省會到塊內任何乙個點路徑上的所有除了省會的點都必須屬於這個塊。n le 1000 一次dfs即可解決。做法如下 實現中有乙個問題,對於乙個兒子,它在棧中積累了不到 b 個點,而在下乙個搜...

bzoj 1086 王室聯邦

餘 人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成員來管理。他的國家有n個城市,編號為1.n。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條直接或間接的道路。為了防止管理太過分散,每個省至少要有b個城市,為了能有效的管理,每個省最多只有3b個城...

BZOJ 1086 王室聯邦

思路 貪心,每次當儲存的兒子大於等於b時,分出乙個塊,這樣每次每個塊至多為2b,這樣剩下的沒有被分的塊小於b,可以加入任意乙個塊,都是合法的。1 include2 include3 include4 include5 include6 int tot,go 200005 first 200005 n...