[bzoj1086]王室联邦

有这样一个贪心的思路:当某一个点搜完某个儿子后,发现当前子树中没有被选入其他省的点数超过了B,就将其当做一个省,并把这个点作为省会(注意:这个点并没有进入这个省),显然可以发现此时每一个省的点数都小于2B另外,当搜完后发现还有小于B的点,那么就将这些点都归入最后一个省,省的点数仍然小于3B

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1005
 4 struct ji{
 5     int nex,to;
 6 }edge[N<<1];
 7 int E,n,m,x,y,head[N],st[N],vis[N],s[N];
 8 void add(int x,int y){
 9     edge[E].nex=head[x];
10     edge[E].to=y;
11     head[x]=E++;
12 }
13 void dfs(int k,int fa){
14     int p=st[0];
15     for(int i=head[k];i!=-1;i=edge[i].nex)
16         if (edge[i].to!=fa){
17             dfs(edge[i].to,k);
18             if (st[0]-p>=m){
19                 s[++s[0]]=k;
20                 while (p!=st[0])vis[st[st[0]--]]=s[0];
21             }
22         }
23     st[++st[0]]=k;
24 }
25 int main(){
26     scanf("%d%d",&n,&m);
27     memset(head,-1,sizeof(head));
28     for(int i=1;i<n;i++){
29         scanf("%d%d",&x,&y);
30         add(x,y);
31         add(y,x);
32     }
33     dfs(1,0);
34     while (st[0])vis[st[st[0]--]]=s[0];
35     printf("%d\n",s[0]);
36     for(int i=1;i<=n;i++)printf("%d ",vis[i]);
37     printf("\n");
38     for(int i=1;i<=s[0];i++)printf("%d ",s[i]);
39 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11247984.html