初始二分圖匹配--増廣路(匈牙利算法)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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章