B - The Accomodation of Students(二分图判断&匹配)
题意:给定若干条有向边,判断该图是否为二分图,并且求最大二分匹配。
思路:用染色法判断二分图+匈牙利算法解决。
时间复杂度:
AC代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=2e2+10;
bool g[N][N];
int n,m,vis[N],mh[N],col[N];
void init(int n){ //初始化
for(int i=1;i<=n;i++)
vis[i]=mh[i]=col[i]=0;
memset(g,0,sizeof g);
}
int bfs(){ //染色法判断二分图
queue<int>q;
q.push(1);
col[1]=1;
while(q.size()){
int u=q.front();q.pop();
for(int v=1;v<=n;v++)
if(g[u][v]){
if(!col[v]) col[v]=-col[u],q.push(v);//放到对立集.
else if(col[u]==col[v]) return 0;
}
}
return 1;
}
int find(int u){ //找妹子.
for(int i=1;i<=n;i++){
if(g[u][i]&&!vis[i]){
vis[i]=1;
if(!mh[i]||find(mh[i]))
{
mh[i]=u;
return 1;
}
}
}
return 0;
}
int fun(){ //计算答案.
int ans=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof vis);
ans+=find(i);
}
return ans;
}
int main(){
while(~scanf("%d%d",&n,&m)){
init(n);
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
g[u][v]=1;
}
if(!bfs()) puts("No");
else printf("%d\n",fun());
}
return 0;
}