1 条题解
-
0
自动搬运
来自洛谷,原作者为

水星湖
菜搬运于
2025-08-24 23:10:33,当前版本为作者最后更新于2025-03-02 10:59:23,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
必然有解。
当图中有 个连通块时,将较小的连通块内所有点放在第一类,剩下大的连通块大小必然 ,任取一个点作为第二类,剩下的作为第三类,显然合法。
否则,当图中仅有一个连通块时,由于 ,则求生成树的过程中至多有 条返祖边,每一条返祖边用并查集合并端点,最后必然剩下 个未合并的集合( 个点至多合并 次),直接输出就好了。
#include <bits/stdc++.h> using namespace std; namespace z { #define int long long const int N = 5e5 + 5; int fa[N], flag[N], vis[N]; vector<int> p[N]; int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } void merge(int x, int y) { x = find(x), y = find(y); if(x != y) fa[x] = y; } void init(int n) { for(int i = 1; i <= n; i++) fa[i] = i, flag[i] = 0, vis[i] = 0, p[i].clear(); } void dfs(int u, int fa) { vis[u] = 1; for(auto v : p[u]) { if(v == fa) continue; if(vis[v]) merge(v, u); else dfs(v, u); } } void solve() { int n, m; cin >> n >> m; init(n); for(int i = 1; i <= m; i++) { int u, v; cin >> u >> v; p[u].push_back(v); p[v].push_back(u); } dfs(1, 0); for(int i = 2; i <= n; i++) if(!vis[i]) { vector<int> a1, a2; for(int j = 1; j <= n; j++) { if(vis[j]) a1.push_back(j); else a2.push_back(j); } if(a1.size() == 1) { cout << 1 << " " << a1[0] << '\n'; cout << 1 << " " << a2[0] << '\n'; cout << a2.size() - 1 << " "; for(auto j : a2) if(j != a2[0]) cout << j << ' '; cout << '\n'; } else if(a2.size() == 1) { cout << 1 << " " << a1[0] << '\n'; cout << 1 << " " << a2[0] << '\n'; cout << a1.size() - 1 << " "; for(auto j : a1) if(j != a1[0]) cout << j << ' '; } else { cout << a1.size() << " "; for(auto j : a1) cout << j << ' '; cout << '\n'; cout << 1 << " " << a2[0] << '\n'; cout << a2.size() - 1 << " "; for(auto j : a2) if(j != a2[0]) cout << j << ' '; } return; } vector<int> ans; for(int i = 1; i <= n; i++) if(find(i) == i) ans.push_back(i); vector<int> a[3]; for(int i = 0; i <= 2; i++) for(int j = 1; j <= n; j++) if(find(j) == ans[i]) a[i].push_back(j), flag[j] = 1; for(int i = 1; i <= n; i++) if(!flag[i]) a[0].push_back(i); for(int i = 0; i <= 2; i++) { cout << a[i].size() << ' '; for(auto j : a[i]) cout << j << ' '; cout << '\n'; } } void main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int T; cin >> T; while(T--) solve(); } #undef int } int main() { z::main(); return 0; }
- 1
信息
- ID
- 11606
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者