zoukankan      html  css  js  c++  java
  • 二分图匹配

    二分图匹配

    一个图可以分成两个部分,其中同一部分的点没有边,不同部分有边相连,求解最多能匹配多少点。

    采用匈牙利算法求解:

    对于每个点的一种匹配

    1.匹配点未选择,将此点与匹配点匹配。

    2.匹配点已与其它点a匹配:将a进行匹配,即重复1,2步骤。

    若满足以上条件之一,则此点可匹配。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxe=1000005;
    const int maxn=2005;
    int a,b,n,m,e,tot;
    int las[maxe],nex[maxe];
    int vis[maxn],lnk[maxn],matched[maxn];
    int read()
    {
    	int ch=0,x=0;while(ch=getchar(),ch<'0'||ch>'9');
    	while(x=x*10+ch-48,ch=getchar(),ch>='0'&&ch<='9');
    	return x;
    }
    void add(int x,int y){nex[++tot]=y;las[tot]=lnk[x];lnk[x]=tot;}
    int find(int x)
    {
    	for(int k=lnk[x];k;k=las[k])
    	{
    		if(vis[nex[k]])continue;
    		vis[nex[k]]=1;
    		if(!matched[nex[k]]){matched[nex[k]]=x;return 1;}
    		if(find(matched[nex[k]])){matched[nex[k]]=x;return 1;}
    	}
    }
    void maxcomplete()
    {
    	int cnt=0;
    	for(int i=1;i<=n;i++)
    	{
    		memset(vis,0,sizeof(vis));
    		if(find(i))cnt++;
    	}
    	printf("%d",cnt);
    }
    int main()
    {
    	n=read();m=read();e=read();
    	for(int i=1;i<=e;i++)
    	{
    		a=read();b=read();
    		if(b>m)continue;
    		add(a,b+n);
    	}
    	maxcomplete();
    	return 0;
    }
    
  • 相关阅读:
    Ubuntu安装deb软件包错误(依赖关系问题)解决
    scrapy抓取的中文结果乱码解决办法
    删除Git记录里的大文件
    Ubuntu18.04 修改DNS
    linux实现ssh免密码登录
    Vim进阶指南
    查找相同图片并重命名
    Markdown进阶指南
    一眼看穿flatMap和map的区别
    Java8简明指南
  • 原文地址:https://www.cnblogs.com/DavidJing/p/10666945.html
Copyright © 2011-2022 走看看