算法:
最大流
建图方式:
外籍飞行员与源点连边,流量为1
英国飞行员与汇点连边,流量为1
外籍与英国飞行员匹配的,流量为inf
小技巧
没有
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 1000000007
using namespace std;
int head[30000],nxt[30000],to[30000],flow[30000];
int dep[30000];
int tot=1;
int m,n;
int st,lt;
void add(int x,int y,int f)
{
tot++;
nxt[tot]=head[x];
head[x]=tot;
to[tot]=y;
flow[tot]=f;
return;
}
bool bfs()
{
memset(dep,0,sizeof(dep));
dep[st]=1;
queue<int>q;
q.push(st);
bool rt=0;
while(!q.empty())
{
int tmp=head[q.front()],ndep=dep[q.front()];
if(!(q.front()^lt))rt=1;
q.pop();
while(~tmp)
{
if((!dep[to[tmp]])&&flow[tmp])
{
q.push(to[tmp]);
dep[to[tmp]]=ndep+1;
}
tmp=nxt[tmp];
}
}
return rt;
}
int dfs(int nn,int f)
{
if(!(nn^lt))return f;
int tmp=head[nn];
while(~tmp)
{
if(flow[tmp]&&dep[to[tmp]]==dep[nn]+1)
{
int tmpv=dfs(to[tmp],min(f,flow[tmp]));
if(tmpv)
{
flow[tmp]-=tmpv;
flow[tmp^1]+=tmpv;
return tmpv;
}
}
tmp=nxt[tmp];
}
return 0;
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&m,&n);
st=n+1,lt=n+2;
for(int i=1;i<=m;i++)
{
add(st,i,1);
add(i,st,0);
}
for(int i=m+1;i<=n;i++)
{
add(i,lt,1);
add(lt,i,0);
}
int x,y;
scanf("%d%d",&x,&y);
while(x!=-1&&y!=-1)
{
add(x,y,inf);
add(y,x,0);
scanf("%d%d",&x,&y);
}
int maxium=0;
//puts("1");
while(bfs())
{
maxium+=dfs(st,inf);
}
if(maxium==0)
{
puts("No Solution!");
return 0;
}
printf("%d\n",maxium);
for(int i=2;i<=tot;i+=2)
{
if(to[i]!=st&&to[i^1]!=st)
if(to[i]!=lt&&to[i^1]!=lt)
if(flow[i^1]!=0)
{
printf("%d %d\n",to[i^1],to[i]);
}
}
return 0;
}