CF1439B Graph Subset Problem
Graph Subset Problem
题目链接。
Problem
给你一个有
请你找到一个大小为
输出方案。
对于每个测试用例:
- 如果找到一个合法点集,在第
行输出1
和子集的大小。在第 行,以任意顺序输出子集的顶点。 - 如果找到一个大小为
的团,那么在第 行输出2
。第 行中,以任意顺序输出该团的顶点。 - 如果没有所需的子集和集团,请输出
-1
。 - 如果存在多个可能的答案,输出其中任意一个。
数据范围:
Sol
首先如果
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
int n, m, K;
int deg[100005], vis[100005], vse[100005];
vector<pii> e[100005];
queue<int> que;
unordered_map<int, int> mp[100005];
int tp, stk[100005];
int Work(int x) {
if ((int) mp[x].size() == K - 1) {
tp = 0;
for (auto i : mp[x])
stk[++tp] = i.first;
int mark = 1;
for (int i = 1; i <= tp && mark; i++)
for (int j = i + 1; j <= tp && mark; j++)
if (!mp[stk[i]].count(stk[j]))
mark = 0;
if (mark) {
printf("2\n%d ", x);
for (int i = 1; i <= tp; i++)
printf("%d%c", stk[i], " \n"[i == tp]);
return 1;
}
}
for (auto i : mp[x]) {
deg[i.first]--;
if (deg[i.first] == K - 1)
que.emplace(i.first);
mp[i.first].erase(x);
}
mp[x].clear(), deg[x] = 0;
return 0;
}
int ans[200005];
void Solve() {
for (int i = 1; i <= n; i++)
deg[i] = vis[i] = 0, e[i].clear(), mp[i].clear();
scanf("%d%d%d", &n, &m, &K);
for (int i = 1, u, v; i <= m; i++) {
scanf("%d%d", &u, &v);
e[u].emplace_back(v, i), e[v].emplace_back(u, i);
deg[u]++, deg[v]++;
}
if (K > ceil(sqrt(2 * m)))
return puts("-1"), void();
for (int i = 1; i <= n; i++)
if (deg[i] < K - 1)
que.emplace(i), vis[i] = 1;
while (!que.empty()) {
int u = que.front();
que.pop();
for (auto i : e[u]) {
int v = i.first, id = i.second;
if (vse[id])
continue;
vse[id] = 1;
deg[v]--;
if (deg[v] < K - 1 && !vis[v])
que.emplace(v), vis[v] = 1;
}
}
for (int i = 1; i <= n; i++)
for (auto j : e[i])
if (!vse[j.second])
mp[i][j.first] = 1;
for (int i = 1; i <= m; i++)
vse[i] = 0;
for (int i = 1; i <= n; i++)
if (deg[i] == K - 1)
que.emplace(i);
int mark = 0;
while (!que.empty()) {
int u = que.front();
que.pop();
if (!mark)
mark = Work(u);
}
if (mark)
return;
int aCnt = 0;
for (int i = 1; i <= n; i++)
if (deg[i] >= K)
ans[++aCnt] = i;
if (!aCnt)
return puts("-1"), void();
printf("1 %d\n", aCnt);
for (int i = 1; i <= aCnt; i++)
printf("%d%c", ans[i], " \n"[i == aCnt]);
}
int main() {
int T;
scanf("%d", &T);
while (T--)
Solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2023-01-11 ABC284E Count Simple Paths 题解
2023-01-11 ABC284D Happy New Year 2023 题解