SSL1338 人员分配【二分图匹配】【匈牙利算法】

SSL1338 人员分配【二分图匹配】【匈牙利算法】_第1张图片
这是一道用匈牙利算法求最大匹配的模板题
怎样做可以看这篇博客,超赞!
这里我只给出解法和详细注释

邻接矩阵

#include
#include
#include
#include
#include
using namespace std;

int a[2010][2010],v[2010],link[1000010];
int m,n,s,x,y,ans;

int dfs(int x)
{
	for(int i=1; i<=m; i++)
	 if(a[x][i]&&!v[i])  //找儿子
	  {
	  	 v[i]=1;   //标记
	  	 int fa=link[i];//将先把当前父亲存在fa里,方便后面折返
	  	 link[i]=x;   //link数组存i的父亲,也就是x
	  	 if(fa==0||dfs(fa))  //这个点无父亲或强占别人点成功匹配后就路径++;
	  	   return 1;
	  	 link[i]=fa;  //折返
	  }
	return 0;  //找完所有儿子发现并没有终止,就说明找不到
}
int main()
{
    cin>>n>>m>>s;
    for(int i=1; i<=s; i++)
     {
     	scanf("%d%d",&x,&y);
        a[x][y]=1;
     }
    for(int i=1; i<=n; i++)
     {
     	memset(v,0,sizeof(v));
     	ans+=dfs(i);
     }
    cout<<ans;
    return 0;
}

邻接表(原理同邻接矩阵)

#include
#include
#include
#include
#include
using namespace std;

int ls[1000010],v[1000010],link[1000010];
int n,m,s,x,y,tot,ans;

struct node
{
	int y,next;
}a[1000010];
void add(int x,int y)
{
	a[++tot].y=y;
	a[tot].next=ls[x];
	ls[x]=tot;
}
int dfs(int x)
{
	for(int i=ls[x]; i; i=a[i].next)
	 {
	 	int y=a[i].y;
	 	if(!v[y])
	 	 {
	 	 	v[y]=1;
	 	 	int fa=link[y];
	 	 	link[y]=x;
	 	 	if(fa==0||dfs(fa))
	 	 	  return 1;
	 	 	link[y]=fa;
	 	 }
	 }
	return 0;
}
int main()
{
    cin>>n>>m>>s;
    for(int i=1; i<=s; i++)
     {
     	cin>>x>>y;
     	add(x,y);
     }
    for(int i=1; i<=n; i++)
     {
     	memset(v,0,sizeof(v));
     	ans+=dfs(i);
     }
    cout<<ans;
    return 0;
}

你可能感兴趣的:(题解,二分图上的操作,#,匈牙利算法)