题目链接:https://ac.nowcoder.com/acm/contest/4370/K
题意:一个n个点m条边的无向图,现给图中的边染色,不允许存在所有边被染色的奇环,求最大的染色数。
思路:因为二分图中不存在奇环,一个无奇环的图必定是一个二分图,所以只需要找一个最大边数的二分图就行了。
枚举 n 个点选与不选,然后如果有边相连的两个点只有一个点被选择这个边就可以作为二分图的一条边,然后枚举所有情况找到最大边数。
#include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<string> #include<algorithm> #include<queue> #include<map> typedef long long ll; using namespace std; inline int read() { int ret = 0, sgn = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') sgn = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { ret = ret * 10 + ch - '0'; ch = getchar(); } return ret * sgn; } inline void Out(int a) { if (a > 9) Out(a / 10); putchar(a % 10 + '0'); } ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } ll lcm(ll a, ll b) { return a * b / gcd(a, b); } ll qpow(ll a, ll b, ll mod) { if (a >= mod) a = a % mod + mod; ll ans = 1; while (b) { if (b & 1) { ans = ans * a; if (ans >= mod) ans = ans % mod + mod; } a *= a; if (a >= mod) a = a % mod + mod; b >>= 1; } return ans; } const int N = 2e2 + 5; int t, n, m; bool u[N], v[N]; bool vis[20]; int cas, ans; void dfs(int x) { if (x == n) { int cnt = 0; for(int i=1; i<=m; i++) cnt += (vis[u[i]] ^ vis[v[i]]); ans = max(ans, cnt); return; } vis[x] = false; dfs(x + 1); vis[x] = true; dfs(x + 1); } int main() { scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); vis[n] = true; ans = 0; for(int i=1; i<=m; i++) { scanf("%d%d",&u[i],&v[i]); } dfs(1); printf("Case #%d: %d ", ++cas, ans); } return 0; }