zoj 4045

假如可以分块,其实很容易分析出来,从叶子往上搜,如果没有搜到公共节点,每个块都 + 1,搜到公共节点,如果两边的和小于等于k,就可以合并,继续往上搜,但是如果大于k,就分不了块,其实还有其他情况也是分不了的。

想到了bfs往上搜,就很容易想到dfs,搜到叶子回溯,这样处理起来就方便多了,只要标记下每个块的第一个节点,记录下来,就很容易做了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int mx = 1e5+10;
 4 vector<int> g[mx], tmp;
 5 int n, k, cnt;
 6 int dep[mx], num[mx], vis[mx];
 7 void dfs(int x, int f){
 8     dep[x] = dep[f] + 1;
 9     if(g[x].size()==1&&g[x][0]==f)
10         return;
11     for(int i = 0; i < g[x].size(); i++){
12         if(g[x][i]==f)continue;
13         dfs(g[x][i], x);
14         if(num[x])
15             num[x]+=num[g[x][i]];
16         if(num[x]==k){
17             cnt++;
18             num[x] = 0;
19             vis[x] = 1;
20             tmp.push_back(x);
21         }
22     }
23 }
24 void dfs2(int x, int f){
25     if(g[x].size()==1&&g[x][0]==f)
26         return;
27     for(int i = 0; i < g[x].size(); i++){
28         if(g[x][i]==f)continue;
29         if(vis[g[x][i]] || dep[x]>dep[g[x][i]])continue;
30         printf(" %d", g[x][i]);
31         vis[g[x][i]] = 1;
32         dfs2(g[x][i], x);
33     }    
34 }
35 inline void init(){
36     cnt = 0;
37     for(int i = 1; i <= n; i++)
38         g[i].clear(), num[i] = 1;
39     tmp.clear();
40     memset(vis, 0, sizeof(vis));
41     memset(dep, 0, sizeof(dep));
42 }
43 int main(){
44     int t;
45     scanf("%d", &t);
46     while(t--){
47         scanf("%d %d", &n, &k);
48         init();
49         int u, v;
50         for(int i = 1; i < n; i++){
51             scanf("%d %d", &u, &v);
52             g[u].push_back(v);
53             g[v].push_back(u);
54         }
55         if(k == 1){
56             puts("YES");
57             for(int i = 1; i <= n; i++)
58                 printf("%d%c", i, i==n?'\n':' ');
59             continue;
60         }
61         if(k == n){
62             puts("YES");
63             for(int i = 1; i <= n; i++)
64                 printf("%d\n", i);
65             continue;
66         }
67         dfs(1, 0);
68         if(cnt == n/k){
69             puts("YES");
70             for(int i = 0; i < tmp.size(); i++){
71                 printf("%d", tmp[i]);
72                 dfs2(tmp[i], tmp[i]);
73                 printf("\n");
74             }
75         }
76         else
77             puts("NO");
78     }
79     return 0;
80 }
View Code

猜你喜欢

转载自www.cnblogs.com/ballballyounoA/p/9976196.html
ZOJ