题目链接:
HDU 2444 The Accomodation of Students
分析:
用BFS判断二分图,用匈牙利算法求最大匹配。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <string>
#include <queue>
using namespace std;
const int MAX_N=210;
const int MAX_M=40010;
int n,m,total;
int head[MAX_N],vis[MAX_N],match[MAX_N],color[MAX_N];
struct Edge{
int to,next;
Edge() {}
Edge(int to,int next) : to(to),next(next) {
}
}edge[MAX_M];
inline void AddEdge(int from,int to)
{
edge[total].to=to;
edge[total].next=head[from];
head[from]=total++;
}
inline bool IsBipartiteGraph()
{
int st=1;
memset(color,-1,sizeof(color));
while(1){
int find=0;
for(int i=st;i<=n;i++){
if(color[i]==-1){
st=i;
find=1;
break;
}
}
if(find==0) break;
queue<int> que;
color[st]=1;//color[i]=0和color[j]=0是不同的两组
que.push(st);
st++;
while(!que.empty()){
int cur=que.front();
que.pop();
for(int i=head[cur];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(color[v]==-1){
color[v]=1-color[cur];
que.push(v);
}else if(color[v]==color[cur]){
return false;
}
}
}
}
return true;
}
inline bool dfs(int u)
{
for(int i=head[u];i!=-1;i=edge[i].next){
int to=edge[i].to;
if(vis[to]==0){
vis[to]=1;
if(match[to]==-1 || dfs(match[to])){
match[to]=u;
match[u]=to;
return true;
}
}
}
return false;
}
inline void solve()
{
int ans=0;
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++){
if(match[i]==-1){
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
}
printf("%d\n",ans);
}
int main()
{
while(~scanf("%d%d",&n,&m)){
total=0;
memset(head,-1,sizeof(head));
for(int i=0;i<m;i++){
int from,to;
scanf("%d%d",&from,&to);
AddEdge(from,to);
}
if(IsBipartiteGraph()==false){
printf("No\n");
continue;
}
solve();
}
return 0;
}