二分图
1. 判定 (染色法)
#include<bits/stdc++.h> using namespace std; const int N = 100010, M = 200010; int n, m; int g[N], cnt, color[N]; struct node{ int nxt,to; }e[M]; bool st[N]; void ins(int a, int b){ cnt ++; e[cnt].to = b; e[cnt].nxt = g[a]; g[a] = cnt; } bool dfs(int x, int c){ color[x] = c; for (int i = g[x]; i; i = e[i].nxt){ int j = e[i].to; if (!color[j]){ if (!dfs(j, 3 - c)) return false; } else if (color[j] == c) return false; } return true; } int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++){ int a, b; scanf("%d%d", &a,&b); ins (a, b); ins(b, a); } bool flag = true; for (int i = 1; i <= n; i++) if(!color[i]){ if(!dfs(i,1)){ flag = 0; break; } } if(flag)puts("Yes"); else puts("No"); return 0; }
例题
洛谷 p1525 关押罪犯
#include<bits/stdc++.h> using namespace std; const int N = 20010, M = 200010; int n, m; int g[N], cnt, color[N], ans; struct node{ int nxt, to, w; }e[M]; bool st[N]; void ins(int a, int b, int w){ cnt ++; e[cnt].to = b; e[cnt].nxt = g[a]; e[cnt].w = w; g[a] = cnt; } bool dfs(int x, int c, int mid){ color[x] = c; for (int i = g[x]; i; i = e[i].nxt){ int j = e[i].to; if (e[i].w <= mid) continue; if (color[j]){ if (color[j] == c) return false; } else if (!dfs(j, 3 - c, mid))return false; } return true; } bool check(int mid){ memset(color, 0, sizeof(color)); for (int i = 1; i <= n; i++) if (color[i] == 0) if(!dfs(i, 1, mid)) return false; return true; } int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++){ int a, b, w; scanf("%d%d%d", &a, &b, &w); ins (a, b, w); ins(b, a, w); } int l = 0, r = 1e9; while(l <= r){ int mid = (l + r) >> 1; if (check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } printf ("%d", ans); return 0; }
2 二分图的最大匹配 (匈牙利算法)
#include<bits/stdc++.h> using namespace std; const int N = 100010, M = 200010; int n1, n2, m; int g[N], cnt, match[N]; struct node{ int nxt,to; }e[M]; bool st[N]; void ins(int a, int b){ cnt ++; e[cnt].to = b; e[cnt].nxt = g[a]; g[a] = cnt; } bool find(int x){ for (int i = g[x]; i; i = e[i].nxt){ int j = e[i].to; if (!st[j]){ st[j] = true; if (match[j] == 0|| find(match[j])){ match[j] = x; return true; } } } return false; } int main(){ scanf("%d%d%d", &n1, &n2, &m); for (int i = 1; i <= m; i++){ int a, b; scanf("%d%d", &a,&b); ins (a, b); } int res = 0; for (int i = 1; i <= n1; i++){ memset(st, false, sizeof(st)); if(find(i)) res++; } printf("%d", res); return 0; }
例题 洛谷 p3386
#include<bits/stdc++.h> using namespace std; const int N = 100010, M = 200010; int n1, n2, m; int g[N], cnt, match[N]; struct node{ int nxt,to; }e[M]; bool st[N]; void ins(int a, int b){ cnt ++; e[cnt].to = b; e[cnt].nxt = g[a]; g[a] = cnt; } bool find(int x){ for (int i = g[x]; i; i = e[i].nxt){ int j = e[i].to; if (!st[j]){ st[j] = true; if (match[j] == 0|| find(match[j])){ match[j] = x; return true; } } } return false; } int main(){ scanf("%d%d%d", &n1, &n2, &m); for (int i = 1; i <= m; i++){ int a, b; scanf("%d%d", &a,&b); ins (a, b); } int res = 0; for (int i = 1; i <= n1; i++){ memset(st, false, sizeof(st)); if(find(i)) res++; } printf("%d", res); return 0; }
浙公网安备 33010602011771号