1. 程式人生 > 其它 >一般圖最大(權)匹配

一般圖最大(權)匹配

一般圖最大匹配

對二分圖進行匈牙利的時候,稱距離

https://uoj.ac/problem/79

#define N 1006
#define M 249506
struct Graph{
	int fir[N],nex[M],to[M],tot;
	inline void add(int u,int v,int flag=1){to[++tot]=v;nex[tot]=fir[u];fir[u]=tot;if(flag) add(v,u,0);}
	inline void clear(){__builtin_memset(fir,0,sizeof fir);tot=0;}
}G;
int n;
int dfscnt,dfn[N],fa[N];
int match[N],pre[N],color[N];
inline int find(int k){return fa[k]==k?k:fa[k]=find(fa[k]);}
inline int getLca(int u,int v){
	u=find(u);v=find(v);dfscnt++;
	while(dfn[u]^dfscnt){
		dfn[u]=dfscnt;
		u=find(pre[match[u]]);
		if(v) lib::swap(u,v);
	}
	return u;
}
int que[N],*left,*right;
inline void dealFlower(int u,int v,int root){//u,v are both even vertex
	while(find(u)^root){
		pre[u]=v;v=match[u];
		if(color[v]==2) color[v]=1,*++right=v;
		if(find(u)==u) fa[u]=root;
		if(find(v)==v) fa[v]=root;
		u=pre[v];
	}
}
inline int bfs(int u){
	__builtin_memset(color+1,0,n*sizeof color[0]);__builtin_memset(pre+1,0,n*sizeof pre[0]);
	for(int i=1;i<=n;i++) fa[i]=i;
	left=que;right=que-1;*++right=u;
	color[u]=1;pre[u]=0;
	while(left<=right){
		u=*left++;
		for(int d,v,i=G.fir[u];i;i=G.nex[i]){
			v=G.to[i];
			if(color[v]==2||find(u)==find(v)) continue;
			if(color[v]) d=getLca(u,v),dealFlower(u,v,d),dealFlower(v,u,d);//flower
			else{
				color[v]=2;color[match[v]]=1;
				if(match[v]) pre[v]=u,*++right=match[v];
				else{
					while(u) d=match[u],match[u]=v,match[v]=u,u=pre[d],v=d;
					return 1;
				}
			}
		}
	}
	return 0;
}