zoukankan      html  css  js  c++  java
  • 【图论】网络流解决二分图最大匹配量问题

    在二分图左边添加一个源点,该源点和二分图中一半的所有结点相连,同时建立一个汇点,将该汇点与另一半中的每一个点连边。
    若bfs返回值为true,则说明仍具有增广路,也就是还可以增加匹配量;否则的话,无法扩大匹配数。
    题目链接Acwing 2175
    image

    #include <bits/stdc++.h>
    #define MEM(a,x) memset(a,x,sizeof(a))
    #define W(a) while(a)
    #define gcd(a,b) __gcd(a,b)
    #define pi acos(-1.0)
    #define PII pair<int,int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define lowbit(x) (x&-x)
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0' && ch<='9')
            x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int MAXN = 1e5+100, N = 400;
    struct edge{
    	int u,v;
    	int cap,flow;
    	int nxt;
    }edges[MAXN];
    int idx,h[MAXN];
    void add(int a,int b,int c)
    {
    	edges[idx]={a,b,c,0,h[a]};
    	h[a]=idx++;
    }
    int n,m,S,T,to[MAXN],cur[N],dis[N];
    inline int dfs(int u,int res)
    {
    	if(u==T||res<=0)
    	  return res;
    	  
    	int f = 0,flow = 0;
    	for(int i=cur[u];~i;i=edges[i].nxt)
    	{
    		cur[u]=i;
    		int v = edges[i].v, u = edges[i].u;
    		if(edges[i].cap>edges[i].flow&&dis[v]==dis[u]+1)
    		{
    			f = dfs(v,min(res,edges[i].cap-edges[i].flow));
    			edges[i].flow+=f;
    			edges[i^1].flow-=f;
    			flow+=f;
    			res-=f;
    		        to[u]=v;
    		}
    	}
    	
    	return flow;
    }
    inline bool bfs()
    {
    	memset(dis,-1,sizeof(dis));
    	queue<int> q;
    	q.push(S);
    	dis[S]=0;
    	while(q.size())
    	{
    		int t = q.front();
    		q.pop();
    		cur[t] = h[t];
    		for(int i=h[t];~i;i=edges[i].nxt)
    		{
    			int v = edges[i].v,u = edges[i].u;
                            if(dis[v]!=-1||edges[i].flow>=edges[i].cap) continue;
                                dis[v] = dis[u] + 1;
                                q.push(edges[i].v);
    		}
    	}
    	if(dis[T]==-1)
    	   return 0;
    	return 1;
    }
    void Dicnic()
    {
    	int ansflow = 0;
    	int cs = 0;
    	int maxflow = 0;
    	for(int i = 1;i<=n;i++)
    	    cur[i] = h[i];
    	while(bfs())
    	{
    		int p = dfs(S,200);
    		cs++;
    		ansflow+=p;
    		maxflow=max(maxflow,p);
    	}
    	cout<<ansflow<<endl;
    }
    int main()
    {
    	memset(h,-1,sizeof(h));
    	memset(to,-1,sizeof(to));
    	n = read(),m = read();
    	S = 0, T = n + m + 1;
    	int a,b;
    	for(int i=1;i<=n;i++)
    	   add(S,i,1),add(i,S,0); 
    	while(1)
    	{
    		a = read(), b = read();
    		if(a==-1&&b==-1) break;
    		add(a,b,1);add(b,a,0);
    	}
    	for(int i=n+1;i<=n+m;i++)
    	   add(i,T,1),add(T,i,0);
    	
    	Dicnic();
    	for(int i=2*n;i<=idx-2*m-1;i+=2)
    	    if(edges[i].flow==edges[i].cap)
    	       cout<<edges[i].u<<" "<<edges[i].v<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    Spark运行模式_基于YARN的Resource Manager的Client模式(集群)
    Spark运行模式_spark自带cluster manager的standalone cluster模式(集群)
    Spark运行模式_Spark自带Cluster Manager的Standalone Client模式(集群)
    Spark运行模式_本地伪集群运行模式(单机模拟集群)
    Spark运行模式_local(本地模式)
    Spark_安装配置_运行模式
    二叉树的非递归遍历算法
    142. Linked List Cycle II
    139. Word Break
    136. Single Number
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15495722.html
Copyright © 2011-2022 走看看