bzoj 1086: [SCOI2005]王室联邦
生活随笔
收集整理的這篇文章主要介紹了
bzoj 1086: [SCOI2005]王室联邦
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
“余”人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的一個成員來管理。他的國家有n個城市,編號為1..n。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條直接或間接的道路。為了防止管理太過分散,每個省至少要有B個城市,為了能有效的管理,每個省最多只有3B個城市。每個省必須有一個省會,這個省會可以位于省內,也可以在該省外。但是該省的任意一個城市到達省會所經過的道路上的城市(除了最后一個城市,即該省省會)都必須屬于該省。一個城市可以作為多個省的省會。聰明的你快幫幫這個國王吧!
解題報告
這題是另一種分塊方法,從下往上做,回溯時入棧,當子樹內的棧元素達到了B,我們就新建一個塊,子數內的棧中元素加入塊中,因為每一個子樹塊\(<B\),所以彈棧時 \(<2*B\),對于最后一個多出來的塊也一定 \(<B\),如果 \(>=B\) 直接新建一個塊,否則和上個塊合并,由于塊內元素 \(<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;}
轉載于:https://www.cnblogs.com/Yuzao/p/7654558.html
總結
以上是生活随笔為你收集整理的bzoj 1086: [SCOI2005]王室联邦的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑显示屏多少钱啊?
- 下一篇: github后端开发面试题大集合(一)