zoukankan      html  css  js  c++  java
  • hiho1122_二分图匈牙利算法

    题目

        给定一个图的N个节点和节点之间的M条边,数据保证该图可以构成一个二分图。求该二分图最大匹配。 
    题目链接:二分图最大匹配 
        首先通过染色法,将图的N个节点分成两个部分;然后通过匈牙利算法求二分图的最大匹配。

    实现

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<string>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<unordered_map>
    #include<unordered_set>
    #include<algorithm>
    using namespace std;
    
    struct Edge{
    	int to;
    	int next;
    };
    Edge gEdges[80005];
    int gEdgeIndex;
    int gHead[10005];
    int gMatch[10005];
    bool gVisited[10005];
    int gColor[10005];
    bool conflict;
    void Init(){
    	gEdgeIndex = 0;
    	memset(gHead, -1, sizeof(gHead));
    	memset(gVisited, false, sizeof(gVisited));
    	memset(gMatch, -1, sizeof(gMatch));
    	memset(gColor, -1, sizeof(gColor));
    	conflict = false;
    }
    void InsertEdge(int u, int v){
    	int e = gEdgeIndex++;
    	gEdges[e].to = v;
    	gEdges[e].next = gHead[u];
    	gHead[u] = e;
    }
    
    void PaintColor(int node, int c){
    	if (conflict)
    		return;
    	gColor[node] = c;
    	for (int e = gHead[node]; e != -1; e = gEdges[e].next){
    		int x = gEdges[e].to;
    		if (gColor[x] == c){
    			conflict = true;
    			return;
    		}
    		if (gColor[x] == -1)
    			PaintColor(x, 1 - c);
    	}
    }
    
    bool Dfs(int node){		
    	for (int e = gHead[node]; e != -1; e = gEdges[e].next){
    		int v = gEdges[e].to;
    		if (!gVisited[v]){  
    			gVisited[v] = true; //置位
    			if (gMatch[v] == -1){
    			//如果对方的阵营中v点还没有匹配,则成功找到一条交错路径
    				gMatch[node] = v;
    				gMatch[v] = node;
    				return true;
    			}
    			else if (Dfs(gMatch[v])){
    			//如果对方阵营中v有匹配点,匹配点肯定在己方阵营,则继续从己方阵营的点
    			//递归
    				gMatch[node] = v;
    				gMatch[v] = node;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    int main(){
    	int n, m, u, v;
    	Init();
    	scanf("%d %d", &n, &m);
    
    	for (int i = 0; i < m; i++){
    		scanf("%d %d", &u, &v);
    		InsertEdge(u, v);
    		InsertEdge(v, u);
    	}
    		
    	for (int i = 1; i <= n; i++)
    		if (gColor[i] == -1)
    			PaintColor(i, 0);
    
    	int ans = 0;
    	for (int i = 1; i <= n; i++){
    		if (gColor[i] == 0 && gMatch[i] == -1){//从固定一方阵营中,不断找未匹配点
    		//寻找交错路,找到一条交错路,则匹配个数增加1
    			memset(gVisited, false, sizeof(gVisited));
    			if (Dfs(i))
    				ans++;
    		}
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    做了6年开发,工资涨不上去,怎么办?(安晓辉,循循善诱的分析)
    Hello World
    服务治理框架
    Range锁(也即范围锁)
    C# .NET Socket
    Net Core应用,在CentOS上运行
    分布式锁,进程锁,线程锁
    TEMPDB
    学会Git
    Docker
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/5612699.html
Copyright © 2011-2022 走看看