二分图匹配 - 学习心得

就是跑匈牙利算法就行了,难点完全在于建图。

模板水题

Link

#include <bits/stdc++.h>
const int N=510;
int n,m,e;
int G[N][N],match[N];
std::bitset<N> vis;

namespace BlackWhiteGraph{
	inline void Init(void){
		scanf("%d%d",&n,&m);
		int a,t;
		for(register int i=1;i<=n;++i){
			scanf("%d",&t);
			while(t--)
				scanf("%d",&a),
				G[i][a]=1;
		}
	}
	bool dfs(int u){
		for(register int i=1;i<=m;++i){
			if(!vis[i]&&G[u][i]){
				vis[i]=true;
				if(!match[i]||dfs(match[i])){
					match[i]=u;
					return true;
				}
			}
		}
		return false;
	}
	int ans=0;
	void Match(void){
		for(register int i=1;i<=n;++i){
			vis.reset();
			if(dfs(i))++ans;
		}
	}
	void output(void){
		printf("%d\n",ans);
		exit(0);
	}
}

using namespace BlackWhiteGraph;
int main(){
	Init();
	Match();
	output();
}

直接无脑套板子然后无脑匈牙利就 AC 了。

#include <bits/stdc++.h>
#define add push_back
using namespace std;
const int N=10100;
int n,m;
vector<int> G[N];
int match[N],use[N];
bitset<N> vis;
bool dfs(int u){
	for(int v : G[u]){
		if(!vis[v]){
			vis[v]=true;
			if(!match[v] || dfs(match[v])){
				use[u]=v,match[v]=u;
				return true; 
			}	
		}
	}
	return false;
}
int main(){
	int ans=0;
	scanf("%d%d",&m,&n);
	int a,b;
	scanf("%d%d",&a,&b);
	while(a!=-1&&b!=-1){
		G[a].add(b);
		scanf("%d%d",&a,&b);
	}
	for(register int i=1;i<=n;++i){
		vis.reset();
		ans+=dfs(i);
	}
	printf("%d\n",ans);
	for(register int i=1;i<=n;++i){
		if(use[i])
			printf("%d %d\n",i,use[i]);
	}
	exit(0);
}

相比于上一道题这道题要记录路径,因为匈牙利模板自带存储路径,直接输出就行了,为什么这个东西也能进24

稍带思维的省选题

四川省选 Day2 T3,但是水得很,直接把两个属性和物品绑在一起然后一步一步跑匈牙利就 AC.

但是这道题还是有一些细节什么的,要匈牙利比较熟悉原理才能 AC.

#include "bits/stdc++.h"
#define ll long long
#define add push_back
using namespace std;
const int N=1e6+10;
int n,m,col;
int vis[N],match[N];
vector<int> G[N];
bool dfs(int u){
	for(int v:G[u])
		if(vis[v]!=col){
			vis[v]=col;
			if(!match[v] || dfs(match[v])){
				match[v]=u;
				return true;
			}
		}
	return false;
}
int main(){
	scanf("%d",&n);
	int mx=-1;
	for(register int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		G[u].add(i);
		G[v].add(i);
	}
	for(register int i=1;i<N;++i){
		++col;if(!dfs(i)){
			printf("%d\n",col-1);
			break;
		}
	}
	
	return 0;
}

P2319 [HNOI2006] 超级英雄

上一题输出路径 AC

很难很难的省选题

鸽。

posted @   q(x)  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示