HDU-2444 The Accomodation of Students
先用染色法判断是否存在奇数环,也就是方案是否可行。然后二分匹配。
#include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <fstream> #include <iostream> #define rep(i, l, r) for(int i=l; i<=r; i++) #define down(i, l, r) for(int i=l; i>=r; i--) #define N 234 #define MAX 1<<30 using namespace std; int read() { int x=0, f=1; char ch=getchar(); while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } struct node{int y, n;} e[N*N]; int fir[N], en; int n, m, k[N], c[N], ans; bool f, b[N]; inline void Add(int x, int y) { en++, e[en].y=y, e[en].n=fir[x], fir[x]=en; en++, e[en].y=x, e[en].n=fir[y], fir[y]=en; } void Search(int x) { int o=fir[x], y=e[o].y; while (o) { if (c[y]==c[x]) f=true; if (!c[y]) { c[y]=3-c[x]; Search(y); } o=e[o].n, y=e[o].y; } } bool Find(int x) { int o=fir[x], y=e[o].y; while (o) { if (!b[y]) { b[y]=1; if (!k[y] || Find(k[y])) { k[y]=x; return true; } } o=e[o].n, y=e[o].y; } return false; } int main() { while (~scanf("%d%d", &n, &m)) { f=false; ans=en=0; rep(i, 1, n) fir[i]=k[i]=c[i]=0; rep(i, 1, m) { int x=read(), y=read(); Add(x, y); } rep(i, 1, n) if (!c[i]) { c[i]=1; Search(i); } if (f) { printf("No\n"); continue; } rep(i, 1, n) if (c[i]==1) { rep(j, 1, n) b[j]=0; if (Find(i)) ans++; } printf("%d\n", ans); } return 0; }