设源点s=0,汇点t=n+1。源点到所有外国飞行员建边,权值为1;所有英国飞行员到汇点建边,权值为1;能匹配的外国飞行员与英国飞行员建边,权值为1。那么问题转化为求最大流,s到t的最大流就是最大匹配。其实就是一道sb题
二分匹配也能做 无聊的可以敲一发
#include "bits/stdc++.h"
using namespace std;
const int inf = 0x3f3f3f3f;
struct edge
{
int v,w,nxt;
}g[10000];
int s,t;
int head[400];
int cur[400];
int cnt;
int dis[400];
int n,m;
void addedge(int u,int v,int w)
{
g[cnt].v=v;
g[cnt].w=w;
g[cnt].nxt=head[u];
head[u]=cnt;
++cnt;
}
bool bfs()
{
memset(dis,0,sizeof(dis));
dis[s]=1;
queue<int>q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=g[i].nxt)
{
int v=g[i].v;
if(dis[v]==0&&g[i].w>0)
{
dis[v]=dis[u]+1;
if(v==t) return 1;
q.push(v);
}
}
}
return dis[t]!=0;
}
int dfs(int u,int flow)
{
if(u==t)return flow;
int ans=0,x=0;
for(int &i=cur[u];i!=-1;i=g[i].nxt)
{
int v=g[i].v;
if((dis[v]==dis[u]+1)&&g[i].w>0)
{
x=dfs(v,min(g[i].w,flow-ans));
g[i].w-=x;
g[i^1].w+=x;
//if(g[i].w)cur[u]=i;
ans+=x;
if(ans==flow) return flow;
}
}
if(ans==0) dis[u]=0;
return ans;
}
int main()
{
scanf("%d%d",&m,&n);
s=0;
t=n+1;
cnt=0;
memset(head,-1,sizeof(head));
memset(g,0,sizeof(g));
for(int i=1;i<=m;i++)
{
addedge(s,i,1);
addedge(i,s,0);
}
for(int i=m+1;i<=n;i++)
{
addedge(i,t,1);
addedge(t,i,0);
}
int x,y;
while(scanf("%d%d",&x,&y)&&(x!=-1&&y!=-1))
{
//if(x>y)swap(x,y);
addedge(x,y,1);
addedge(y,x,0);
}
int ans=0;
while (bfs())
{
for(int i=0;i<=n;i++)
{
cur[i]=head[i];
}
ans+=dfs(0,inf);
}
if(ans==0)puts("No Solution!");
else printf("%d\n",ans);
}