BZOJ 1086 SCOI2005 王室聯邦

2022-08-21 02:18:12 字數 1406 閱讀 5330

維護乙個棧,從任意乙個節點開始 dfs,在回溯時加入到棧中。

dfs每乙個子樹之後,若相對於剛進入該節點時棧的大小,新增加的節點超過 b,就將它們分為一塊

這樣分完保證不超過 2b,而整個dfs結束之後,若棧中還有節點,就把它們歸為最後一塊

#include #define pb push_back

#define fi first

#define se second

#define pii pair#define lp p << 1

#define rp p << 1 | 1

#define mid ((l + r) >> 1)

#define ll long long

#define db double

#define rep(i,a,b) for(int i=a;i=a;i--)

#define edg int ccnt=1,head[n],to[n*2],ne[n*2];void addd(int u,int v)void add(int u,int v)

#define edgc int ccnt=1,head[n],to[n*2],ne[n*2],c[n*2];void addd(int u,int v,int w)void add(int u,int v,int w)

#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])

const int mod = 1e9 + 7;

void m(int &x)

int qp(int a,int b=mod-2)

char buf[1 << 21], *p1 = buf, *p2 = buf;

inline char getc()

inline int _()

while (ch >= '0' && ch <= '9')

return x * f;

}const int n = 1111;

edgint n, b, st[n], top, belong[n], province[n], cnt;

void dfs(int u, int f)

} st[++top] = u;

}int main()

dfs(1, 0);

while (top) belong[st[top--]] = cnt;

printf("%d\n", cnt);

rep (i, 1, n + 1) printf("%d%c", belong[i], " \n"[i == n]);

rep (i, 1, cnt + 1) printf("%d%c", province[i], " \n"[i == cnt]);

return 0;

}

bzoj1086 scoi2005 王室聯邦

題目鏈結 本來是來學樹上分塊的,沒想到正解是貪心 dfs。題意 求將樹分為幾個聯通塊,每個聯通塊大小大於b小於3b,是否可行。solution1 題都沒看就翻了題解。發現時貪心 dfs。一遍dfs即可。注意到以x為根節點時,其兒子s,則子樹s中與s相連的節點的連通塊,如果要構成乙個省,既可以s作為省...

bzoj1086 SCOI2005 王室聯邦

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

BZOJ 1086 SCOI2005 王室聯邦

啊啊啊啊啊啊啊啊啊啊啊啊 又是一道赤果果的水水模板題 沒辦法啊我太弱了。好吧 這是一道樹分塊 原題戳對其實你們依然不用戳 餘 人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成 員來管理。他的國家有n個城市,編號為1.n。一些城市之間有道路相連,任意兩個不同的...