Problem Statement
There is a simple undirected graph $G$ with $N$ vertices and $M$ edges. The vertices are numbered $1, 2, \ldots, N$, and the $i$-th edge is an undirected edge connecting vertices $A_i$ and $B_i$.
You can repeat the following two operations in any order and any number of times:
- Add one undirected edge to $G$
- Remove one undirected edge from $G$
Find the minimum number of operations to make $G$ a simple undirected graph where all vertices have degree $2$.
What is a simple undirected graph?
A simple undirected graph refers to an undirected graph that has no self-loops and no multi-edges.
Constraints
- $3 \leq N \leq 8$
- $0 \leq M \leq \frac{N(N-1)}{2}$
- The graph $G$ given in the input is a simple undirected graph.
- All input values are integers.
Solving
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
void solve()
{
int n,m;
cin >> n >> m;
vector<vector<bool>> G(n+1,vector<bool>(n+1,false));
vector<int> P(n+1); // 图的排列,表示其下标和值的连边构成的图
vector<bool> vis(n+1,false);
for(int i=1;i<=m;i++)
{
int u,v;
cin >> u >> v;
G[u][v] = G[v][u] = true;
}
int ans = INF;
// 枚举所有可能构成的,满足条件的图,并计算原图与当前满足条件图的差异,即达到当前图需要的操作次数
auto dfs = [&](auto &&self,int x) -> void // 当前枚举到第x位
{
if(x == n + 1)
{
vector<vector<bool>> T(n+1,vector<bool>(n+1,false));
for(int i=1;i<=n;i++) T[i][P[i]] = T[P[i]][i] = true;
int res = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
{
res += T[i][j] ^ G[i][j];
}
}
ans = min(ans,res);
return;
}
for(int i=1;i<=n;i++)
{
// 排除不满足所有点度数为2的环:单点自环,两点有重边。
if(!vis[i] and i != x and !(i < x and P[i] == x))
{
vis[i] = true;
P[x] = i;
self(self,x+1);
vis[i] = false;
}
}
};
dfs(dfs,1);
cout << ans << endl;
}
|