专栏文章
题解:AT_abc412_d [ABC412D] Make 2-Regular Graph
AT_abc412_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miozcxwm
- 此快照首次捕获于
- 2025/12/03 03:37 3 个月前
- 此快照最后确认于
- 2025/12/03 03:37 3 个月前
解法
首先可以发现,每一个所有节点度数都为 的图一定是循环图。
循环图最小节点数为 ,故整幅图最多只能分为两个循环图。
分情况讨论。
分为单独一部分
观察到题目中的 ,可以枚举每一个可能的循环图。
由于节点数一样,我们只需要枚举所有可能的顺序,再取所有答案中的最小值即可。
分为两部分
沿用上面的思路,我们可以先枚举第一部分的大小,再将整个顺序列表分为一二两部分继续求答案即可。
代码
CPP#include <bits/stdc++.h>
#define int long long
const int N = 100;
const int Mod = 1e9 + 7;
using namespace std;
int n, m;
bool g[N][N], tg[N][N];
inline void solve(vector<int> vec, int st, int ed)
{
for (int i = st; i <= ed; i++)
{
int nxt = vec[i == ed ? st : i + 1];
int pre = vec[i == st ? ed : i - 1];
tg[vec[i]][nxt] = 1;
tg[nxt][vec[i]] = 1;
tg[vec[i]][pre] = 1;
tg[pre][vec[i]] = 1;
}
}
inline int get()
{
int cnt = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cnt += tg[i][j] != g[i][j];
}
}
return cnt / 2;
}
inline void clear()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
tg[i][j] = 0;
}
}
}
signed main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
g[u][v] = 1;
g[v][u] = 1;
}
vector<int> vec;
for (int i = 1; i <= n; i++)
{
vec.push_back(i);
}
int mi = 1e9;
do
{
// 1 个圈
clear();
solve(vec, 0, n - 1);
mi = min(mi, get());
// 2 个圈
for (int i = 3; i <= n - 3; i++)
{
clear();
solve(vec, 0, i - 1);
solve(vec, i, n - 1);
mi = min(mi, get());
}
} while (next_permutation(vec.begin(), vec.end()));
cout << mi;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...