飞行员配对方案问题 网络流||二分图匹配

简单的二分图模型复习下最大流和二分图匹配

然而这题的数据没有SJ测不了,只能测前面的匹配数对不对

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define efo(i,x) for(int i=last[x];i!=0;i=e[i].next)
using namespace std;
inline LL read()
{
	LL d=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
	return d*f;
}
#define N 107
#define S 0
#define T 106
#define inf 100000000
struct edge
{
	int f,y,next;
}e[N*N*2];
struct ansss
{
	int x,y;
}ans[N];
int anss=0;
int last[N],ne=1;
int nm,n;

void add(int x,int y,int f)
{
	e[++ne].f=f;e[ne].y=y;e[ne].next=last[x];last[x]=ne;
}
void add2(int x,int y)
{
	add(x,y,1);add(y,x,0);
}

queue<int>q;
int h[N+5];
bool bfs(int s,int t)
{
	memset(h,-1,sizeof(h));
	q.push(s);h[s]=1;
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		efo(i,now)
		if(e[i].f&&h[e[i].y]==-1)
		{
			h[e[i].y]=h[now]+1;
			q.push(e[i].y);
		}
	}
	if(h[t]==-1)return 0;
	else return 1;
}

int dfs(int k,int t,int maxf)
{
	if(k==t)return maxf;
	int f,ret=0;
	efo(i,k)
	if(e[i].f&&h[e[i].y]==h[k]+1)
	{
		f=dfs(e[i].y,t,min(maxf-ret,e[i].f));
		e[i].f-=f;
		e[i^1].f+=f;
		ret+=f;
		if(ret==maxf)return ret;
	}
	return ret;
}		

int dinic(int s,int t)
{
	int ret=0;
	while(bfs(s,t))ret+=dfs(s,t,inf);
	return ret;
}

bool getans(int k,int pre)
{
	if(k==S)return 1;
	efo(i,k)
	if(e[i].f&&(e[i].y<=nm||k==T))
	{
		if(getans(e[i].y,k))
		{
			if(k!=S&&k!=T)
			{
				if(pre!=S&&pre!=T)
				{
					ans[++anss].x=k;
					ans[anss].y=pre;
				}
			}
		}
	}
	return 0;
}
	
bool anscom(ansss a,ansss b)
{
	return a.x<b.x;
}

int main()
{
	nm=read(),n=read();
	int xx=read(),yy=read();
	while(xx+yy!=-2)
	{
		add2(xx,yy);
		xx=read(),yy=read();
	}
	fo(i,1,nm)add2(S,i);
	fo(i,nm+1,n)add2(i,T);
	cout<<endl<<endl<<dinic(S,T)<<endl;
	getans(T,-1);
	sort(ans+1,ans+anss+1,anscom);
	fo(i,1,anss)
	cout<<ans[i].x<<' '<<ans[i].y<<endl;
	return 0;
}

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<bitset>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
#define efo(i,x) for(int i=last[x];i!=0;i=e[i].next)
using namespace std;
inline LL read()
{
	LL d=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
	return d*f;
}
#define N 105
#define M 105
struct edge
{
	int y,next;
}e[N*M];
int last[N],ne=0;
int n,nm,m,ans=0;
int l[N],r[N];
bitset<N>y;

void add(int x,int y)
{
	e[++ne].y=y;e[ne].next=last[x];last[x]=ne;
}

bool match(int x)
{
	efo(i,x)
	if(y[e[i].y]==0)
	{
		y[e[i].y]=1;
		if(l[e[i].y]==0||match(l[e[i].y]))
		{
			l[e[i].y]=x;
			r[x]=e[i].y;
			return 1;
		}
	}
	return 0;
}

int main()
{
	nm=read(),n=read();
	int x=read(),yy=read();
	while(x+yy!=-2)
	{
		add(x,yy-nm);
		x=read(),yy=read();
	}
	memset(l,0,sizeof(l));
	memset(r,0,sizeof(r));
	fo(i,1,nm)
	{
		y.reset();
		if(match(i))ans++;
	}
	cout<<ans<<endl;
	fo(i,1,nm)
	if(r[i])
	{
		cout<<i<<' '<<r[i]+nm<<endl;
	}
	return 0;
}


你可能感兴趣的:(网络流,二分图匹配)