ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

一般图最大匹配(奇环处理) 带花树算法

2021-11-18 21:04:55  阅读:223  来源: 互联网

标签:花树 pre get int void 算法 奇环 match define


P6113 【模板】一般图最大匹配

匈牙利算法最大的问题在于无法处理带奇环的图,如果存在奇环,那么程序会T掉

带花树算法就是用于处理奇环的问题

#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-5
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
//#define ls(p) e[p].l
//#define rs(p) e[p].r
//#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int mod=998244353;
const int N=1e5+5;//?????????? 4e8.
int n,m;
namespace GP
{
	queue < int > q;
	struct node
	{
		int ver,next;
	}e[N];
	int tot,head[N];
	int num=0;
	int fa[N],v[N],pre[N],match[N],dfn[N];
	void add(int x,int y)
	{
		e[++tot].ver=y;
		e[tot].next=head[x];
		head[x]=tot;
	}
	void addedge(int x,int y)
	{
		add(x,y);add(y,x);
	}
	int get(int x)
	{
		return fa[x]==x?x:fa[x]=get(fa[x]);
	}
	int lca(int x,int y)
	{
		num++;
		x=get(x),y=get(y);
		while(dfn[x]!=num)
		{
			dfn[x]=num;
			x=get(pre[match[x]]);
			if(y)  swap(x,y);
		}
		return x;
	}
	void blossom(int x,int y,int z)
	{
		while(get(x)!=z)
		{
			pre[x]=y;y=match[x];
			if(v[y]==2)
			{
				v[y]=1;
				q.push(y);
			}
			if(x==get(x))  fa[x]=z;
			if(y==get(y))  fa[y]=z;
			x=pre[y];
		}
	}
	bool bfs(int s)
	{
		while(q.size())  q.pop();
		for(re i=1;i<=n;i++)  fa[i]=i,v[i]=pre[i]=0;
		v[s]=1,q.push(s);
		while(q.size())
		{
			int x=q.front();q.pop();
			for(re i=head[x];i;i=e[i].next)
			{
				int y=e[i].ver;
				if(v[y]==2||get(x)==get(y))  continue;
				if(!v[y])
				{
					v[y]=2;pre[y]=x;
					if(!match[y])
					{
						for(re u=y,lst;u;u=lst)
						{
							lst=match[pre[u]];
							match[u]=pre[u];
							match[pre[u]]=u;
						}
						return 1;
					}
					v[match[y]]=1;
					q.push(match[y]);
				}
				else
				{
					int w=lca(x,y);
					blossom(x,y,w);blossom(y,x,w);
				}
			}
		}
		return 0;
	}
}
void solve()
{
	cin>>n>>m;
	for(re i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		GP::addedge(x,y);
	}
	int p=0;
	for(re i=1;i<=n;i++)  if(!GP::match[i])  p+=GP::bfs(i);
	printf("%d\n",p);
	for(re i=1;i<=n;i++)  printf("%d ",GP::match[i]);
}
signed main()
{
//	freopen("P1505_1.txt", "r", stdin);
//	freopen("Aout.txt", "w", stdout);
    int T=1;
//    cin>>T;
    for(int index=1;index<=T;index++)
    {
//        printf("Case #%lld: ",index);
        solve();
//        puts("");
    }
    return 0;
}
/*

10 5
hbtngdflmj
1 10 1
2 9 0
3 8 1
4 7 0
5 6 1


*/

标签:花树,pre,get,int,void,算法,奇环,match,define
来源: https://blog.csdn.net/lcl1234567890lcl/article/details/121410046

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有