bzoj 1086: [SCOI2005]王室联邦
Description
“余”人國的國王想重新編制他的國家。他想把他的國家劃分成若干個(gè)省,每個(gè)省都由他們王室聯(lián)邦的一個(gè)成員來管理。他的國家有n個(gè)城市,編號(hào)為1..n。一些城市之間有道路相連,任意兩個(gè)不同的城市之間有且僅有一條直接或間接的道路。為了防止管理太過分散,每個(gè)省至少要有B個(gè)城市,為了能有效的管理,每個(gè)省最多只有3B個(gè)城市。每個(gè)省必須有一個(gè)省會(huì),這個(gè)省會(huì)可以位于省內(nèi),也可以在該省外。但是該省的任意一個(gè)城市到達(dá)省會(huì)所經(jīng)過的道路上的城市(除了最后一個(gè)城市,即該省省會(huì))都必須屬于該省。一個(gè)城市可以作為多個(gè)省的省會(huì)。聰明的你快幫幫這個(gè)國王吧!
解題報(bào)告
這題是另一種分塊方法,從下往上做,回溯時(shí)入棧,當(dāng)子樹內(nèi)的棧元素達(dá)到了B,我們就新建一個(gè)塊,子數(shù)內(nèi)的棧中元素加入塊中,因?yàn)槊恳粋€(gè)子樹塊\(<B\),所以彈棧時(shí) \(<2*B\),對(duì)于最后一個(gè)多出來的塊也一定 \(<B\),如果 \(>=B\) 直接新建一個(gè)塊,否則和上個(gè)塊合并,由于塊內(nèi)元素 \(<2*B\),所以加入后 \(<3*B\)
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=1005;
int n,B,head[N],num=0,nxt[N<<1],to[N<<1],cnt=0,st[N],top=0,fa[N],bel[N];
void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
void dfs(int x,int last){int u,s=top;for(int i=head[x];i;i=nxt[i]){u=to[i];if(u==last)continue;dfs(u,x);if(top-s>=B){fa[++cnt]=x;while(top!=s)bel[st[top--]]=cnt;}}st[++top]=x;
}
void work()
{int x,y;scanf("%d%d",&n,&B);for(int i=1;i<n;i++){scanf("%d%d",&x,&y);link(x,y);link(y,x);}dfs(1,1);while(top)bel[st[top--]]=cnt;printf("%d\n",cnt);for(int i=1;i<=n;i++)printf("%d ",bel[i]);puts("");for(int i=1;i<=cnt;i++)printf("%d ",fa[i]);
}int main(){work();return 0;}
轉(zhuǎn)載于:https://www.cnblogs.com/Yuzao/p/7654558.html
總結(jié)
以上是生活随笔為你收集整理的bzoj 1086: [SCOI2005]王室联邦的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑显示屏多少钱啊?
- 下一篇: github后端开发面试题大集合(一)