一般图的最大匹配(模板)

题:http://uoj.ac/problem/79

没什么好说的,只是区别于二分图

算法:带花树算法

#include<bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=b;i>=a;i--)
const int N=550;
int n,head[N],pre[N],match[N],f[N],col[N],cmp[N],tot;
const int M=5e5+5;
struct node{
    int u,v,nextt;
}e[M];
int num;
void addedge(int u,int v){
    e[num].v=v;
    e[num].nextt=head[u];
    head[u]=num++;
}
int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}
int lca(int x,int y){//整个lca实现比较巧妙,由于是BFS,那么这两个点在当前奇环上的深度一定相等,交替暴力寻找lca即可。
    tot++;
    x=find(x),y=find(y);
    while(cmp[x]!=tot){
        cmp[x]=tot;
        x=find(pre[match[x]]);
        if(y)
            swap(x,y);
    }
    return x;
}
queue<int>que;
void make(int x,int y,int w){//缩环(开花)过程
    while(find(x)!=w){
        pre[x]=y,y=match[x];//x是原本的黑点,y是原本的白点,将原本的pre边变成双向。
        if(col[y]==2)//若y还是白点则染黑
            col[y]=1,que.push(y);
        if(find(x)==x)
            f[x]=w;
        if(find(y)==y)
            f[y]=w;
        x=pre[y];
    }

}
int  solve(int st){
    while(!que.empty())
        que.pop();
    que.push(st);
    fo(i,1,n)
        f[i]=i,pre[i]=col[i]=0;
    col[st]=1;//1 is black
    while(!que.empty()){
        int u=que.front();
        que.pop();
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(find(v)==find(u)||col[v]==2)
                continue;//如果找到一个已经缩过的奇环或者偶环则跳过
            if(!col[v]){
                col[v]=2,pre[v]=u;
                if(!match[v]){//找到增广路
                    for(int x=v,y;x;x=y){//返回修改匹配
                        y=match[pre[x]];
                        match[x]=pre[x];
                        match[pre[x]]=x;
                    }
                    return 1;
                }
                //否则将其匹配点加入队列
                col[match[v]]=1;
                que.push(match[v]);
            }
            else{
                int LCA=lca(u,v);
                make(u,v,LCA);
                make(v,u,LCA);//以上分别修改到lca的路径以及v到lca的路径(环的两半)
            }
        }
    }
    return 0;
}
int main(){
    int m;
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    fo(i,1,m){
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    int ans=0;
    fo(i,1,n)
        if(!match[i])
            ans+=solve(i);
    printf("%d\n",ans);
    fo(i,1,n)
        printf("%d ",match[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/starve/p/11716598.html

时间: 2024-08-06 00:58:51

一般图的最大匹配(模板)的相关文章

求无权图的最大匹配---匈牙利算法

匈牙利算法 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名,,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. [先介绍几个概念] 匹配:在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点.例如,图3.图4 中红色的边就是图 2 的匹配. 我们定义匹配点.匹配边.未匹配点.非匹配边,它们的含义非常显然.例如图 3中 1.4.5.7为匹配点,其他顶点为未匹配点:1-5.4-7为匹配边,其他边为

POJ 2226 缩点建图+二分图最大匹配

这个最小覆盖但不同于 POJ 3041,只有横或者竖方向连通的点能用一块板子覆盖,非连续的,就要用多块 所以用类似并查集方法,分别横向与竖向缩点,有交集的地方就连通,再走一遍最大匹配即可 一开始还有点没想清楚缩点怎么写,其实就是横向和竖向分别缩一下,不要混在一起,否则很麻烦,要注意一下 #include <iostream> #include <cstdio> #include <cstring> using namespace std; char mat[900][9

精品思维导图,流程图模板分享

大家在平时的日常办公中是不是市场发现有时候做一件事,明明有了想法,有了思路,可到实行的时候却忘记了呢?这时好我们该怎么办呢?细心的朋友肯定会将想法与思路用思维导图进行梳理,这样实行起来就更有条理,便于记忆.下面小编将在迅捷画图里分享给大家几款思维导图与流程图模板,可以直接套用的哦! 思维导图模板 2019年毕业生就业月历 年终财务总结思维导图 英语课文学习思维导图 高中函数内容思维导图 流程图模板 淘宝购物流程 系统流程图 教育教学质量监控体系流程 收款业务流程图 好了,今天的分享就到这里了,迅

思维导图,流程图模板整合

思维导图与流程图在工作中都是经常使用的,出现频率较高的,有些不会绘制的或者是刚接触这一类的图表形式的都会选择使用模板来完成工作,但是很多朋友却不知道模板在×××,今天要给大家分享的是几款孩子走精美的思维导图,流程图模板整合,需要使用的朋友可以自取进行使用. **模板所在地:迅捷画图 流程图: 1.电商运营流程图 这是一份关于电商运营的流程图,详细的介绍了新用户.老用户未付款状态下的解决方法. 2.<电商物流仓储流程图> 这是一份关于电商物流仓储流程图,详细的概述了电商物流仓储的流程,提高了工作

唯美思维导图,流程图模板分享及在迅捷画图中绘制方法

在绘制思维导图时,我们除了自己对框架进行搭建之外还可以选择使用套用模板进行编辑使用,这两种方法都是比较简单并且实用的,下面给大家分享几款绘制唯美的思维导图,流程图模板以及怎样在迅捷画图中绘制该模板的操作方法介绍,希望下面的操作方法可以帮助到大家. 思维导图模板: 从百草园到三味书屋读书笔记总结思维导图 <从百草园到三味书屋>是鲁迅写的一篇童年妙趣生活的回忆性散文描绘了一个奇趣无穷的儿童乐园,其间穿插"美女蛇"的传说和冬天雪地捕鸟的故事,与三味书屋形成了鲜明的对比,以下思维导

URAL 1099 Work scheduling 一般图的最大匹配 带花树算法(模板)

R - Work scheduling Time Limit:500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 1099 Description There is certain amount of night guards that are available to protect the local junkyard from possible junk r

Ural1099 Work Scheduling 一般图的最大匹配

Ural1099 给定无向图, 求最大匹配. 在寻找增广路的过程中,可能出现一个奇环,这时候把奇环收缩,成为一朵"花",并在新图上继续增广. 为了记录匹配关系,需要在花中寻找路径,每一条增广路径都可以通过把"花"展开还原回去(因为一个奇环上的两段路径必然一奇一偶) 给出代码,,理解不了就当模版吧 类似的算法还有朱刘算法 #include<iostream> #include<cstdio> #include<cstdlib> #i

HDU 2063 过山车 二分图最大匹配(模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=2063 https://www.renfei.org/blog/bipartite-matching.html 交替路:从一个未匹配点出发,依次经过非匹配边.匹配边.非匹配边-形成的路径叫交替路. 增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path) 增广路有一个重要特点:非匹配边比匹配边多一条.因此,研究增广路的意义是改进匹配.

(模板)网页游戏用的“内容区”的“图赏影音”模板

网页游戏,没图赏影音用到的 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=