初始二分图匹配--増广路(匈牙利算法)poj3041

http://poj.org/problem?id=3041

二分图匹配的详解:https://www.renfei.org/blog/bipartite-matching.html

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
//以下说的左顶点集是指増广路的未匹配点起点所在的顶点集合 
//---------------------------------------------------- 
//result_x[i]=j;表示左顶点集的点i连接到右顶点集的点j,同理。。 
int result_x[505],result_y[505]; 
int vis[505];//vis[i]标记点i有没有被走过 
vector<int > p[505];//相当于线性表 


bool dfs(int u){//左顶点集合的未匹配点 
	ll len=p[u].size();
	for(int i=0;i<len;i++){//寻找顶点u在右顶点集和的邻接点 
		int v=p[u][i];
		if(!vis[v]) {//如果此邻接点在此次dfs找増广路的过程中没有被走过
			vis[v]=1;//加入到増广路 
		if(!result_y[v]||dfs(result_y[v])){//!result_y[v]如果此邻接点未匹配过(不属于前一个匹配M) 
			                               //dfs(result_y[v])如果此邻接点匹配过,继续判断以此点为未匹配起点的新的増广路是否存在
			result_y[v]=u;//找到增广路,就可以交换増广路中的匹配边和未匹配边 
			result_x[u]=v;
			return true; 
		}
		}
	}
	return false;
}

int getnum(int n){
	memset(result_x,0,sizeof(result_x));
	memset(result_y,0,sizeof(result_y));
	int ans=0;
	for(int u=1;u<=n;u++){
		if(!result_x[u]){//如果是未匹配点可以找増广路 
			memset(vis,0,sizeof(vis));
			if(dfs(u)){
				ans++;
			}
		}
	}
	return ans;
}

int main(){
	ll n,k,x,y;
	cin>>n>>k;
	for(int i=0;i<k;i++){
		cin>>x>>y;
		p[x].push_back(y);
	}
	cout<<getnum(n)<<endl;
	
	return 0;
}
发布了186 篇原创文章 · 获赞 38 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43746332/article/details/103114238