【UOJ #79】—一般图最大匹配(带花树)
模板
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
cs int N=1005,M=100005;
vector<int> e[N];
int n,m;
int id[N],pre[N],match[N],vis[N],fa[N],tim;
inline int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
inline void add(int u,int v){
e[u].pb(v),e[v].pb(u);
}
queue<int> q;
inline int Lca(int u,int v){
tim++;
while(vis[u]!=tim){
if(u){
u=find(u);
if(vis[u]==tim)return u;
vis[u]=tim;
if(match[u]!=0)u=find(pre[match[u]]);
else u=0;
}
swap(u,v);
}
return u;
}
inline void update(int u,int v,int z){
while(find(u)!=z){
pre[u]=v;int p=match[u];
if(id[p]==1){id[p]=0,q.push(p);}
if(find(p)==p){fa[p]=z;}
if(find(u)==u){fa[u]=z;}
v=p,u=pre[v];
}
}
inline bool bfs(int s){
for(int i=1;i<=n;i++)id[i]=-1,fa[i]=i;
while(!q.empty())q.pop();
q.push(s),id[s]=0;
while(!q.empty()){
int u=q.front();q.pop();
for(int &v:e[u]){
if(id[v]==-1){
pre[v]=u,id[v]=1;
if(!match[v]){
int now=v;
while(now!=0){
int t=pre[now],last=match[t];
match[t]=now,match[now]=t;
now=last;
}
return 1;
}
id[match[v]]=0,q.push(match[v]);
}
else if(id[v]==0&&find(u)!=find(v)){
int lca=Lca(u,v);
update(u,v,lca),update(v,u,lca);
}
}
}
return 0;
}
inline void solve(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}
int ans=0;
for(int i=1;i<=n;i++)if(!match[i]&&bfs(i))ans++;
cout<<ans<<'\n';
for(int i=1;i<=n;i++)cout<<match[i]<<" ";
}
int main(){
solve();
}