acdream1233 Royal Federation (构造?)
http://acdream.info/problem?pid=1233
Andrew Stankevich's Contest (3)
ASC 3
Royal FederationSpecial JudgeTime Limit: 10000/5000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others)
Problem DescriptionThe king of Fooland has recently decided to reorganize his kingdom. Inspired by the democracy processes in neighbouring countries, he decided to convert his kingdom into Royal Federation. The Royal Federation would consist of several provinces, each headed by its governor. There are N cities in his kingdom, numbered from 1 to N. Some cities are connected by roads. Roads are designed in such a way, that for each city there is exactly one way to get to any other city by the roads, not passing through any city more than once. To prevent wastes for maintaining too small provinces, each province must contain at least B cities. However, to keep governments effective, each province must contain at most 3B cities. Each province must have its governer headquaters in some city. This city may be outside the province itslef, but one must be able to get to the city with governer headquaters of his province in such a way, that all intermediate cities that he visits on his way belong to his province (and only the terminal city may be from another province). One city may contain headquaters for several provinces. Help the king to see his plans fulfilled. InputThe first line of the input file contains two integer numbers - N and B (1 <= N <= 10 000, 1 <= B <= N). Next N - 1 lines contain descriptions of roads, each line contains two integer numbers - the cities the road connects. OutputIf it is impossible to fulfil king's plans of reorganization, output 0 on the first line of the output file. In the other case output K - the number of provinces in your plan of the Royal Federation. After that output N integer numbers ranging from 1 to K - for each city output the number of the province it belongs to. Finally output K integer numbers —— the cities where the capitals of the provinces must be located in. Sample Input8 2 1 2 2 3 1 8 8 7 8 6 4 6 6 5 Sample Output3 2 1 1 3 3 3 3 2 2 1 8 SourceAndrew Stankevich Contest 3
Manager |
题意:
国家有N个城市,任意城市可以到达任意城市,是一棵树。国王要给这些城市分省份。每个省份最少B个城市,最多3B个城市。每个省有一个首府,首府不一定是这个省的城市,只是首府到这个省各个城市只能经过这个省的城市。给出N和B,求分配方案,输出有多少个省,各个城市属于哪个省,每个省的首府是哪个城。(一个城可以是多个城的首府)(无解则输出0)
题解:
DFS,回溯时给当前点的各个子树分配颜色(省份),只要攒够不小于B个城市,就直接新生成一个颜色把它们刷了,首府是当前城市(所以可以当前点的不同分支刷成同一种颜色)。搞完所有点后,最后把剩下小于B个城市也刷成最后一种颜色。
正确性:主要就是看把最后剩下的小于B个城市也刷成最后一种颜色是否符合要求。根据我的刷法,一种颜色的城市数肯定是小于等于(2B-2)(两个含有B-1个城市的枝刷成的),最后剩下的没颜色的城市加上去也不会超过3B,OK!
然后是无解的情况,无解时颜色数为0,直接输出就行了,不用特判。
(这种范围比较宽的构造性题一般都比较水,大家居然都不做,搞的我也不敢做……
(其实一下也没想明白,慢慢才想出来的
代码:
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set> 10 #include<stack> 11 #include<queue> 12 using namespace std; 13 #define ll long long 14 #define usll unsigned ll 15 #define mz(array) memset(array, 0, sizeof(array)) 16 #define mf1(array) memset(array, -1, sizeof(array)) 17 #define minf(array) memset(array, 0x3f, sizeof(array)) 18 #define REP(i,n) for(i=0;i<(n);i++) 19 #define FOR(i,x,n) for(i=(x);i<=(n);i++) 20 #define RD(x) scanf("%d",&x) 21 #define RD2(x,y) scanf("%d%d",&x,&y) 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) 23 #define WN(x) printf("%d\n",x); 24 #define RE freopen("D.in","r",stdin) 25 #define WE freopen("huzhi.txt","w",stdout) 26 #define mp make_pair 27 #define pb push_back 28 #define pf push_front 29 #define ppf pop_front 30 #define ppb pop_back 31 const double pi=acos(-1.0); 32 const double eps=1e-10; 33 34 const int maxn=11111; 35 36 struct Edge { 37 int v,next; 38 } e[maxn*2]; 39 int head[maxn],en; 40 41 void addedge(int x,int y) { 42 e[en].v=y; 43 e[en].next=head[x]; 44 head[x]=en++; 45 } 46 47 int n,B; 48 49 int f[maxn]; 50 int sd[maxn]; 51 int ans; 52 53 inline void fil(const int &x , const int &fa , const int &ys) { 54 f[x]=ys; 55 for(int i=head[x]; i!=-1; i=e[i].next) 56 if(e[i].v!=fa && f[e[i].v]==0) fil(e[i].v , x , ys); 57 } 58 59 bool used[maxn]; 60 inline int dfs(const int &x) { 61 int i; 62 vector<pair<int,int> >s; 63 used[x]=1; 64 for(i=head[x]; i!=-1; i=e[i].next) { 65 if(used[e[i].v]==0){ 66 int t=dfs(e[i].v); 67 if(t!=0)s.pb(mp(e[i].v , t)); 68 } 69 } 70 int sum=0,j=0,k; 71 i=0; 72 int size=s.size(); 73 while(i<size) { 74 pair<int,int> pp=s[i]; 75 sum+=pp.second; 76 if(sum>=B) { 77 ans++; 78 sd[ans]=x; 79 for(k=j; k<=i; k++) { 80 fil(s[k].first , x , ans); 81 sum-=s[k].second; 82 } 83 j=i+1; 84 } 85 i++; 86 } 87 sum++; 88 if(sum>=B) { 89 ans++; 90 sd[ans]=x; 91 i=size-1; 92 for(k=j; k<=i; k++) { 93 fil(s[k].first , x , ans); 94 sum-=s[k].second; 95 } 96 f[x]=ans; 97 sum--; 98 } 99 return sum; 100 } 101 102 103 void farm() { 104 ans=0; 105 mz(used); 106 mz(f); 107 int t=dfs(1); 108 if(f[1]==0)fil(1,0,ans); 109 } 110 111 int main() { 112 int i,x,y; 113 while(RD2(n,B)!=EOF) { 114 en=0; 115 mf1(head); 116 REP(i,n-1) { 117 RD2(x,y); 118 addedge(x,y); 119 addedge(y,x); 120 } 121 farm(); 122 printf("%d\n",ans); 123 if(ans!=0) { 124 if(n>=1)printf("%d",f[1]); 125 FOR(i,2,n)printf(" %d",f[i]); 126 puts(""); 127 printf("%d",sd[1]); 128 FOR(i,2,ans)printf(" %d",sd[i]); 129 puts(""); 130 } 131 } 132 return 0; 133 }