Make 2-Regular Graph

Atcoder Beginner Contest 412 D

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;
    }
Licensed under CC BY-NC-SA 4.0
Member of the Qilu University Of Technology ACM-ICPC Association
Built with Hugo
Theme Stack designed by Jimmy