Arbiter
题意
给定 n n n 个点和 m m m 条边,要求删除最少数量的边,使图中没有奇环
n ≤ 15 , m ≤ 300 n \leq 15,m \leq 300 n≤15,m≤300
思路
没有奇环的图是二分图
我们可以直接从定义入手,用二进制枚举二分图的两个颜色的点,删除两个集合各自内部的所有边即可,答案取 m i n min min
时间复杂度: O ( m ⋅ 2 n ) O(m \cdot 2 ^ n) O(m⋅2n)
#include<bits/stdc++.h>
#define fore(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;const int INF=0x3f3f3f3f;
const long long INFLL=1e18;typedef long long ll;std::vector<std::vector<int>> g;int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int t;std::cin >> t;while(t--){int n, m;std::cin >> n >> m;g.assign(n + 1, std::vector<int>());std::vector<std::pair<int, int>> edge(m);fore(i, 0, m){int u, v;std::cin >> u >> v;edge[i] = {u, v};g[u].push_back(v);g[v].push_back(u);}int ans = m;fore(S, 1, 1 << n){std::vector<int> sta(n);fore(j, 0, n) sta[j] = (S >> j & 1);int n1 = 0, n0 = 0;fore(i, 0, n){n1 += sta[i];n0 += (sta[i] == 0);}if(!n1 || !n0) continue;int cnt = 0;for(auto [u, v] : edge) cnt += (sta[u] == sta[v]);ans = std::min(ans, cnt);}std::cout << ans << endl;}return 0;
}