• 二分图匹配


    二分图匹配

    这是一个绿与被绿的故事......

    首先二分图就是一张图能分成两个点集,集合内部没有连边,两集合之间有若干连边

    现在有这么一张图

    要求最多有多少对点能匹配成功

    首先,我们给张起灵匹配。我们发现他只能和吴邪匹配,那好,我们给他们安排上。

    现在这张图长这样(张海客:族长你不要我们了)

    现在给王胖子匹配,他只爱云彩,安排上。

    到苏万了。我们发现苏万是一个花心人缘好的人,但我们选他最想选的人也就是黑瞎子给他。

    到解雨臣了。我们发现,解雨臣喜欢的黑瞎子被苏万抢了,于是解雨臣带着自己的蝴蝶刀和解家去和苏万商量。苏万还有喜欢的人,况且黑瞎子也不想要他,于是苏万哭着说师傅不要他了,迫于威胁答应了,他选了杨好,解雨臣和黑瞎子配对成功。

    到霍道夫了。他的杨好又被苏万抢了。于是苏万成了众矢之的,解家霍家追着他打霍道夫又去和苏万商议。苏万打不过,只好选了黎簇又被黎簇揍了一通,可怜的苏万。

    最后,这张图长这样

    很愉快,所有人都匹配成功。

    二分图匹配思想就是这样。上代码

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,m,e,head[2000010],cnt,ans,vis[2000010],f[2000010];
    struct node{
    	int to,next;
    }a[2000010]; 
    void add(int x,int y){
    	a[++cnt].to=y,a[cnt].next=head[x],head[x]=cnt;
    }
    bool dfs(int u,int time){
    	for(int i=head[u],v;v=a[i].to,i;i=a[i].next)
    		if(vis[v]^time){ 
    			vis[v]=time;
    			if((!f[v])||dfs(f[v],time)){//若未被匹配或者能商量,就将两人匹配
    				f[v]=u;return true;
    			}
    		}
    	return false;
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&e);
    	for(int i=1,a,b;i<=e;++i){
    		scanf("%d%d",&a,&b);
    		if(a>m||b>m) continue;
    		add(a,b);
    	}
    	for(int i=1;i<=n;++i)
    		if(dfs(i,i)) ans++;
    	printf("%d",ans);
    	return 0;
    }
    

    欢迎指正评论O(∩_∩)O~~

  • 相关阅读:
    基于范围的for循环
    ML.NET技术研究系列-2聚类算法KMeans
    SQLServer常用运维SQL整理
    ML.NET技术研究系列-1入门篇
    Kafka基本知识整理
    .NetCore技术研究-EntityFramework Core 3.0 Preview
    容器技术研究-Kubernetes基本概念
    特来电混沌工程实践-混沌事件注入
    .Net Core技术研究-Span<T>和ValueTuple<T>
    Visual Studio Git本地Repos和GitHub远程Repos互操作
  • 原文地址:https://www.cnblogs.com/kylinbalck/p/9879214.html
Copyright © 2020-2023  润新知