The Accomodation of Students HDU - 2444
思路:
染色判断二分图,二分图求最大匹配裸题。
code:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 2e2 + 5;
struct node{
int u, v, next;
} g[maxn * maxn * 2];
int head[maxn], match[maxn], color[maxn], reg[maxn], cnt;
bool vis[maxn];
void init(int n){
cnt = 0;
for(int i = 1; i <= n; i++){
head[i] = -1;
match[i] = 0;
vis[i] = false;
color[i] = -1;
}
}
void add(int u, int v){
g[cnt].u = u;
g[cnt].v = v;
g[cnt].next = head[u];
head[u] = cnt++;
}
bool bfs(int u){
queue<int> qu;
while(qu.size()) qu.pop();
qu.push(u);
color[u] = 0;
bool flag = true;
int p;
while(qu.size() && flag){
p = qu.front();
qu.pop();
for(int i = head[p]; i != -1; i = g[i].next) {
int q = g[i].v;
if(color[p] == color[q]){
flag = false;
break;
}
else if(color[q] == -1){
color[q] = !color[p];
qu.push(q);
}
}
}
return flag;
}
bool dfs(int u){
for(int i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if(vis[v]) continue;
vis[v] = true;
if(!match[v] || dfs(match[v])){
match[v] = u;
return true;
}
}
return false;
}
int main(){
int n, m, x, y;
while(~scanf("%d%d", &n, &m)){
init(n);
for(int i = 1; i <= m; i++){
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
bool flag = false;
for(int i = 1; i <= n; i++)
if(color[i] == -1)
if(!bfs(i)) {
printf("No\n");
flag = true;
break;
}
if(flag) continue;
int tot = 0, ans = 0;
for(int i = 1; i <= n; i++)
if(color[i] == 0) reg[++tot] = i;
for(int i = 1; i <= tot; i++){
for(int j = 1; j <= n; j++) vis[j] = false;
if(dfs(reg[i])) ans++;
}
printf("%d\n", ans);
}
return 0;
}