【网络流二十四题】搭配飞行员

题目

解析:

二分图最大匹配模板

code:

#include <bits/stdc++.h>
using namespace std;

const int Maxn=105;
const int Maxm=3000;
const int inf=1e9;
int n,m,size=-1,s,t,ans;
int first[Maxn],dep[Maxn],tmp[Maxn];
struct shu{int to,next,len;}edge[Maxm<<2];

inline void build(int x,int y,int z)
{
	edge[++size].next=first[x],first[x]=size,edge[size].to=y,edge[size].len=z;
}

inline void init()
{
	int x,y;
	scanf("%d%d",&n,&m),s=0,t=n+1;
	memset(first,-1,sizeof(first));
	for(int i=1;i<=m;i++) build(s,i,1),build(i,s,0);
	for(int i=m+1;i<=n;i++) build(i,t,1),build(t,i,0);
	while(scanf("%d",&x)!=EOF)
	{
	  scanf("%d",&y);
	  build(x,y,1),build(y,x,0);
	}
}

inline bool bfs()
{
	queue<int>q;
	for(int i=0;i<=n+1;i++) dep[i]=0;
	q.push(s),dep[s]=1;
	while(q.size())
	{
	  int p=q.front();q.pop();
	  for(int u=first[p];u!=-1;u=edge[u].next)
	  {
	  	int to=edge[u].to;
	  	if(dep[to] || !edge[u].len) continue;
	  	dep[to]=dep[p]+1,q.push(to);
	  	if(to==t) return 1;
	  }
	}
	return 0;
}

inline int dfs(int p,int flow)
{
	if(p==t) return flow;
	int sum=0;
	for(int &u=tmp[p];u!=-1;u=edge[u].next)
	{
	  int to=edge[u].to;
	  if(dep[to]!=dep[p]+1 || !edge[u].len) continue;
	  int minn=dfs(to,min(flow-sum,edge[u].len));
	  sum+=minn,edge[u].len-=minn,edge[u^1].len+=minn;
	  if(sum==flow) break;
	}
	return sum;
}

inline void solve()
{
	while(bfs())
	{
	  for(int i=0;i<=n+1;i++) tmp[i]=first[i];
	  ans+=dfs(s,inf);
	}
	cout<<ans;
}

int main()
{
	init();
	solve();
	return 0;
}
posted @ 2021-07-29 11:41  Tarjan_Zeng  阅读(45)  评论(0)    收藏  举报