日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bzoj1086[SCOI2005]王室联邦

發布時間:2024/10/12 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj1086[SCOI2005]王室联邦 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門

Description

  “余”人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的一個成
員來管理。他的國家有n個城市,編號為1..n。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條
直接或間接的道路。為了防止管理太過分散,每個省至少要有B個城市,為了能有效的管理,每個省最多只有3B個
城市。每個省必須有一個省會,這個省會可以位于省內,也可以在該省外。但是該省的任意一個城市到達省會所經
過的道路上的城市(除了最后一個城市,即該省省會)都必須屬于該省。一個城市可以作為多個省的省會。聰明的
你快幫幫這個國王吧!

Input

  第一行包含兩個數N,B(1<=N<=1000, 1 <= B <= N)。接下來N-1行,每行描述一條邊,包含兩個數,即這
條邊連接的兩個城市的編號。

Output

  如果無法滿足國王的要求,輸出0。否則輸出數K,表示你給出的劃分方案中省的個數,編號為1..K。第二行輸
出N個數,第I個數表示編號為I的城市屬于的省的編號,第三行輸出K個數,表示這K個省的省會的城市編號,如果
有多種方案,你可以輸出任意一種。

Sample Input

8 2
1 2
2 3
1 8
8 7
8 6
4 6
6 5

Sample Output

3
2 1 1 3 3 3 3 2
2 1 8

題解

如果有一顆子樹,我們把它上面的點劃分到一個省以內,那么省會一定是這個子樹上的點或者子樹的根節點的父親節點。那么我們可以判斷出除非n<b,否則題目一定有解。因此我們考慮對其分塊,用一個棧維護。從根節點向下dfs,每次向棧中壓入當前訪問的值。每當子樹大小大于b時,就將其記錄成一塊,根為省會。最后一定剩下不到b個節點,我們分的每一塊的大小一定大于等于b且小于2b。所以我們把剩下的節點全部丟到最后一塊中,就可以求出一個解了。

代碼

1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 int ans=0,n,cnt=1,t=0,b; 8 struct node{ 9 int to,nxt; 10 }e[10010]; 11 int head[1010],bel[1010],mas[1010],sta[2010]; 12 void add(int u,int v){ 13 e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt; 14 e[++cnt].to=u;e[cnt].nxt=head[v];head[v]=cnt; 15 } 16 void dfs(int x,int fa){ 17 int now=t; 18 int i; 19 for(i=head[x];i;i=e[i].nxt){ 20 if(e[i].to!=fa){ 21 dfs(e[i].to,x); 22 if(t-now>=b){ 23 mas[++ans]=x; 24 while(t!=now){ 25 bel[sta[t--]]=ans; 26 } 27 } 28 } 29 } 30 sta[++t]=x; 31 } 32 int main(){ 33 scanf("%d%d",&n,&b); 34 if(n<b){ 35 printf("0\n");return 0; 36 } 37 int i,j,x,y; 38 for(i=1;i<n;++i){ 39 scanf("%d%d",&x,&y); 40 add(x,y); 41 } 42 dfs(1,0); 43 while(t) bel[sta[t--]]=ans; 44 printf("%d\n",ans); 45 if(ans==0) return 0; 46 for(i=1;i<=n;++i){ 47 printf("%d ",bel[i]); 48 } 49 printf("\n"); 50 for(i=1;i<=ans;++i) printf("%d ",mas[i]); 51 printf("\n"); 52 return 0; 53 }

?

轉載于:https://www.cnblogs.com/lazytear/p/9080371.html

總結

以上是生活随笔為你收集整理的bzoj1086[SCOI2005]王室联邦的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。