一般图匹配--带花树算法

来源:互联网 发布:android程序员转型 编辑:程序博客网 时间:2024/05/14 20:44

思路很简单,但是写起来很迷,没有想象中那么容易实现。

#include<iostream>#include<cstdio>#include<cstring> #include<queue>using namespace std;const int maxn=505,maxm=250005;int link[maxn],pre[maxn],fa[maxn],col[maxn],n;int Begin[maxn],Next[maxm],to[maxm],e;bool vis[maxn];queue<int>q;void add(int u,int v){to[++e]=v,Next[e]=Begin[u],Begin[u]=e;}int find(int x){if(x==fa[x])return x;else return fa[x]=find(fa[x]);}void update(int u,int c){while(u!=c){int v=link[u],tmp=pre[v];if(find(tmp)!=c)pre[tmp]=v;if(col[v]==2)col[v]=1,q.push(v);fa[find(u)]=fa[find(v)]=find(tmp);u=tmp;}}void con(int u,int v){memset(vis,0,sizeof(vis));int c;for(int i=u;i;i=pre[link[i]])vis[i=find(i)]=1;for(int i=v;i;i=pre[link[i]])if(vis[i=find(i)]){c=i;break;}if(find(u)!=c)pre[u]=v;if(find(v)!=c)pre[v]=u;update(u,c),update(v,c);}void bfs(int st){memset(col,0,sizeof(col));memset(pre,0,sizeof(pre));for(int i=1;i<=n;i++)fa[i]=i;while(!q.empty())q.pop();q.push(st),col[st]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=Begin[u];i;i=Next[i]){int v=to[i];if((link[v]==u)||(find(u)==find(v))||(col[v]==2))continue;if(col[v]==1)con(u,v);else if(link[v]){pre[v]=u;col[v]=2;col[link[v]]=1;q.push(link[v]);}else{pre[v]=u;while(v){int tmp=link[u];link[v]=u,link[u]=v;v=tmp,u=pre[v];}return;}}}}int main(){int m,u,v,res=0;scanf("%d%d",&n,&m);while(m--){scanf("%d%d",&u,&v);add(u,v),add(v,u);}for(int i=1;i<=n;i++)if(!link[i])bfs(i);for(int i=1;i<=n;i++)if(link[i])res++;printf("%d\n",res>>1);for(int i=1;i<=n;i++)printf("%d ",link[i]);return 0;}


1 1
原创粉丝点击