q
这道题是一道比较经典的分治题目,需要我们用到分治思想解题。我们把图进行递归地二分,在每个子图中进行划分找到
考虑如何递归二分图。首先二分
考虑如何计算
这个操作描述地比较麻烦,实际上可以看做是从
代码如下:这道题是一道比较经典的分治题目,需要我们用到分治思想解题。我们把图进行递归地二分,在每个子图中进行划分找到
考虑如何递归二分图。首先二分
考虑如何计算
这个操作描述地比较麻烦,实际上可以看做是从
代码如下:这道题是一道比较经典的分治题目,需要我们用到分治思想解题。我们把图进行递归地二分,在每个子图中进行划分找到
考虑如何递归二分图。首先二分
考虑如何计算
这个操作描述地比较麻烦,实际上可以看做是从
代码如下:这道题是一道比较经典的分治题目,需要我们用到分治思想解题。我们把图进行递归地二分,在每个子图中进行划分找到
考虑如何递归二分图。首先二分
考虑如何计算
这个操作描述地比较麻烦,实际上可以看做是从
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int n, m, f[N][30], cnt, size[N], flag[N];
vector<int> g[N], c[N];
struct node {
int u, v, nxt;
} e[N << 1];
void ad(int u, int v) {
e[++cnt].u = u; e[cnt].v = v; e[cnt].nxt = flag[u]; flag[u] = cnt;
e[++cnt].u = v; e[cnt].v = u; e[cnt].nxt = flag[v]; flag[v] = cnt;
}
int deep[N], st[N], ed[N], top, T;
void dfs1(int u, int fa) {
size[u] = 1;
for (int i = 0; i < g[u].size(); i++) {
int to = g[u][i];
if (to == fa) continue;
deep[to] = deep[u] + 1;
dfs1(to, u);
size[u] += size[to];
}
}
void dfs2(int u, int fa, int dis) {
if (dis > size[u]) return ;
if (st[deep[u]] == 0) st[deep[u]] = u;
ed[deep[u]] = u;
if (dis == size[u]) {
for (int i = deep[u]; i >= 1; i--) {
int x = st[i], y = ed[i];
c[x].push_back(y); c[y].push_back(x);
}
return ;
} else if (dis < size[u]) {
int to = -1;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (v == fa) continue;
if (size[v] > size[to]) to = v;
}
dfs2(to, u, dis + size[to]);
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (v == fa || v == to) continue;
dfs2(v, u, size[v]);
}
}
}
void dfs(int u) {
for (int i = 1; i <= 20; i++) {
f[u][i] = f[f[u][i - 1]][i - 1];
}
for (int i = 0; i < c[u].size(); i++) {
int to = c[u][i];
if (to == f[u][0]) continue;
f[to][0] = u; dfs(to);
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v; scanf("%d%d", &u, &v);
ad(u, v);
}
deep[1] = 1; dfs1(1, 0);
dfs2(1, 0, 1);
for (int i = 1; i <= n; i++) {
sort(c[i].begin(), c[i].end(), [](int a, int b){return size[a] < size[b];});
if (c[i].size() > 0 && size[c[i][0]] >= size[i] * 2) {
c[i].erase(c[i].begin());
}
}
dfs(1);
int k;
for (k = 1; k <= n; k++) {
bool flag = 1;
for (int i = 1; i <= n; i++) {
if (size[i] > k) {
int u = i;
for (int j = 20; j >= 0; j--) {
if (f[u][j] != 0 && size[f[u][j]] <= k) {
u = f[u][j];
}
}
if (flag && !c[u].empty()) {
flag = 0;
for (int l = 0; l < c[u].size(); l++) {
if (size[c[u][l]] <= k) continue;
int v = c[u][l];
printf("%d ", 2);
printf("%d ", size(u));
while (u != f[v][0]) printf("%d ", u), u = f[u][0];
printf("%d\n", u);
printf("%d ", size(v));
while (v != f[u][0]) printf("%d ", v), v = f[v][0];
printf("%d\n", v);
break;
}
} else {
printf("%d ", 1);
printf("%d ", size(i));
while (size(u) < k) u = f[u][0];
while (size(i) > k) {
printf("%d ", i); i = f[i][0];
}
printf("%d\n", u);
}
}
}
if (!flag) break;
}
printf("%d %d\n", k, cnt );
return 0;
}