• 二分图--二分图的几种模型


    二分图最大匹配

    二分图匹配:每个左部点最多与一个右部点相连,每个右部点最多与一个左部点相连

    算法流程:

    如果后来的和以前的发生矛盾,则以前的优先退让。

    如果以前的退让之后没有点与之相连,则以前的拒绝退让,新来的去寻找下一个匹配。

    如果新来的谁也匹配不上,就匹配不上吧:

    学会了二分图最大匹配后,另外几种模型也可求解。

    最小点覆盖

    最小点覆盖:选取最少的点,使得所有的点与至少一个被选取点距离不超过1,或选取最少的点,使得所有边都至少与一个被选取点相连

    方法:最小点覆盖=最大匹配

    最大独立集

    最大独立集:选取最多的点,使得其中任意两点互不相达

    方法:最大独立集 = 点总数 - 最大匹配

    最小边覆盖

    最小边覆盖:选取最少的边使得所有的点被至少一条边覆盖

    方法:最小边覆盖 = 总点数 - 最大匹配

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=5e4+10;
    int read(){
    	int x=1,a=0;char ch=getchar();
    	while (ch<'0'||ch>'9'){if (ch=='-') x=-1;ch=getchar();}
    	while (ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
    	return x*a;
    }
    struct node{
    	int to,next;
    }ed[maxn];
    int head[maxn],tot;
    int matc[maxn],vis[maxn];
    void add(int u,int to){
    	ed[++tot].to=to;
    	ed[tot].next=head[u];
    	head[u]=tot;
    }
    int n,m,e;
    bool dfs(int x){
    	for(int i = head[x];i;i=ed[i].next){
    		int to=ed[i].to;
    		if (vis[to]) continue; vis[to]=1;
    		if (matc[to]==0||dfs(matc[to])){
    			matc[to]=x; 
    			return true;
    		}
    	}
    	return false;
    }
    int main(){
    	n=read(),m=read(),e=read();
    	for (int i = 1;i <= e;i++){
    		int u,v;
    		u=read(),v=read();
    		add(u,v);
    	}
    	int ans=0;
    	for(int i = 1;i <= n;i++){
    		memset(vis,0,sizeof(vis));
    		if (dfs(i)) ans++;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    JavaScript实现的抛物线运动效果
    圆周运动
    正则表达式种双反斜杠问题\
    自定义日期格式-炫酷
    css font的简写规则
    匀速运动及案例
    微博发布
    无缝滚动和无缝滚动-缓存
    Dojo实现Tabs页报错(一)
    我的2013之十八年寒窗磨利剑,初出江湖还看今朝
  • 原文地址:https://www.cnblogs.com/very-beginning/p/13844287.html
Copyright © 2020-2023  润新知