过去做的都是二分图匹配 即 同一个集合里的点 互相不联通

但是如果延伸到一般图上去 求一个一般图的最大匹配 就要用带花树来解决

带花树模板 用来处理一个无向图上的最大匹配 
看了一会还是不懂  抄了一遍kuangbin的模板熟悉了一下

还有一个一般图最大权匹配 保存下来了VFK菊苣的模板题代码当作板子 http://uoj.ac/submission/16359

但愿以后的比赛永远也遇不到 .. 遇到了也能抄对 .. 抄错了也能过 ..

R ural1099

kuangbin模板

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
#define L long long
int n ;
bool g[255][255];
int match[255] ;
bool inque[255] , inpath[255] , inblo[255] ;
int head , tail ;
int que[255] ;
int st , fi ;
int newbase ;
int fa[255] , base[255] ;
int cnt ;
void creag(){
int u ,v ;
memset(g , false , sizeof(g)) ;
scanf("%d",&n ) ;
while(scanf("%d%d" , &u , &v) !=EOF){
g[u][v] = g[v][u] = true ;
}
}
void push(int u){
que[tail] = u ;
tail ++ ;
inque[u] = true ;
}
int pop(){
int res = que[head] ;
head ++ ;
return res ;
}
int findca(int u , int v) {
memset(inpath , false , sizeof(inpath)) ;
while(true){
u = base[u];
inpath[u] = true ;
if(u == st)break;
u = fa[match[u]] ;
}
while(true){
v = base[v] ;
if(inpath[v])break;
v = fa[match[v]] ;
}
return v ;
}
void reset(int u ){
int v ;
while(base[u] != newbase ){
v = match[u];
inblo[base[u]] = inblo[base[v]] = true ;
u = fa[v] ;
if(base[u] != newbase )fa[u] = v;
}
}
void blocon(int u , int v ){
newbase = findca(u,v);
memset(inblo , false , sizeof(inblo)) ;
reset(u) ;
reset(v) ;
if(base[u] != newbase )fa[u] = v ;
if(base[v] != newbase )fa[v] = u ;
for(int tu = 1 ;tu <= n ; tu ++ ){
if(inblo[base[tu]]){
base[tu] = newbase ;
if(!inque[tu] )push(tu ) ;
}
}
}
void findatp(){
memset(inque , false , sizeof(inque)) ;
memset(fa , 0 , sizeof(fa)) ;
for(int i = 1; i <= n ; i ++ ){
base[i] = i ;
}
head = tail = 1 ;
push(st) ;
fi = 0 ;
while(head < tail ){
int u = pop() ;
for(int v = 1; v <= n ; v ++ ){
if(g[u][v] && (base[u] != base[v] ) && (match[u ] != v)){
if((v == st) || ((match[v] > 0) && fa[match[v]] > 0) ){
blocon(u,v);
}
else if (fa[v] == 0) {
fa[v] = u ;
if(match[v] > 0) {
push(match[v]) ;
}
else {
fi = v ;
break ;
}
}
}
}
}
}
void ap(){
int u ,v , w ;
u = fi ;
while(u > 0) {
v = fa[u] ;
w = match[v] ;
match[v] = u ;
match[u] = v;
u = w ;
}
}
void edmonds (){
memset(match , 0 ,sizeof(match)) ;
for(int u = 1; u <= n; u ++ ){
if(match[u] == 0) {
st = u ;
findatp() ;
if(fi > 0){
ap() ;
}
}
}
} void print(){
cnt = 0;
for(int u = 1; u <= n ; u ++ ){
if(match[u] > 0)cnt ++ ;
}
printf("%d\n",cnt);
for(int u = 1; u <= n ; u ++ ){
if(u < match[u]) {
printf("%d %d\n",u , match[u]) ;
}
}
}
int main(){
creag();
edmonds() ;
print() ;
}

S hdu4687

给出一群pair 输出那些 不在任何最大匹配中的pair 的编号

不在任何最大匹配的pair 只能是 它的两个端点上 都有必选的pair 所以这个pair不能做相邻pair的替代 因为如果替代 另一个端点上的pair就不能选了

所以 枚举每条边 把这条边的两个端点上的所以边都去掉 如果损失了两个匹配 那么这条边就不在任何一个匹配中

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
#define L long long
int n , m ;
bool g[255][255];
int match[255] ;
bool inque[255] , inpath[255] , inblo[255] ;
int head , tail ;
int que[255] ;
int st , fi ;
int newbase ;
int fa[255] , base[255] ;
int cnt ; int input[255][2] ;
int output[255] ; bool bf[255][255] ; void creag(){
int u ,v ;
memset(g , false , sizeof(g)) ;
memset(bf , false , sizeof(bf)) ;
for(int i = 1; i <= m ; i ++ ){
scanf("%d%d",&u,&v);
g[u][v] = g[v][u] = true ;
bf[u][v] = bf[v][u] = true ;
input[i][0] = u ;
input[i][1] = v ;
}
}
void push(int u){
que[tail] = u ;
tail ++ ;
inque[u] = true ;
}
int pop(){
int res = que[head] ;
head ++ ;
return res ;
}
int findca(int u , int v) {
memset(inpath , false , sizeof(inpath)) ;
while(true){
u = base[u];
inpath[u] = true ;
if(u == st)break;
u = fa[match[u]] ;
}
while(true){
v = base[v] ;
if(inpath[v])break;
v = fa[match[v]] ;
}
return v ;
}
void reset(int u ){
int v ;
while(base[u] != newbase ){
v = match[u];
inblo[base[u]] = inblo[base[v]] = true ;
u = fa[v] ;
if(base[u] != newbase )fa[u] = v;
}
}
void blocon(int u , int v ){
newbase = findca(u,v);
memset(inblo , false , sizeof(inblo)) ;
reset(u) ;
reset(v) ;
if(base[u] != newbase )fa[u] = v ;
if(base[v] != newbase )fa[v] = u ;
for(int tu = 1 ;tu <= n ; tu ++ ){
if(inblo[base[tu]]){
base[tu] = newbase ;
if(!inque[tu] )push(tu ) ;
}
}
}
void findatp(){
memset(inque , false , sizeof(inque)) ;
memset(fa , 0 , sizeof(fa)) ;
for(int i = 1; i <= n ; i ++ ){
base[i] = i ;
}
head = tail = 1 ;
push(st) ;
fi = 0 ;
while(head < tail ){
int u = pop() ;
for(int v = 1; v <= n ; v ++ ){
if(g[u][v] && (base[u] != base[v] ) && (match[u ] != v)){
if((v == st) || ((match[v] > 0) && fa[match[v]] > 0) ){
blocon(u,v);
}
else if (fa[v] == 0) {
fa[v] = u ;
if(match[v] > 0) {
push(match[v]) ;
}
else {
fi = v ;
break ;
}
}
}
}
}
}
void ap(){
int u ,v , w ;
u = fi ;
while(u > 0) {
v = fa[u] ;
w = match[v] ;
match[v] = u ;
match[u] = v;
u = w ;
}
}
void edmonds (){
memset(match , 0 ,sizeof(match)) ;
for(int u = 1; u <= n; u ++ ){
if(match[u] == 0) {
st = u ;
findatp() ;
if(fi > 0){
ap() ;
}
}
}
} int print(){
int cnt = 0;
for(int u = 1; u <= n ; u ++ ){
if(match[u] > 0 && u < match[u]){
cnt ++ ;
}
}
return cnt ;
}
int main(){
while(scanf("%d%d" , &n, &m )!=EOF){
creag();
edmonds() ;
int res = print() ;
int ans = 0 ;
for(int i = 1; i <= m; i ++ ){
int u = input[i][0] ;
int v = input[i][1] ;
for(int k = 1; k <= n ; k ++ ){
for(int j = 1; j <= n; j ++ )
g[k][j] = bf[k][j] ;
}
for(int j = 1; j <= n ; j ++ ){
g[j][v] = g[v][j] = g[u][j] = g[j][u] = false ; }
edmonds() ;
int r = print() ;
if(r == res - 2){
ans ++ ;
output[ans] = i ;
}
}
printf("%d\n",ans) ;
for(int i = 1; i <= ans ;i ++ ){
printf("%d",output[i]) ;
if(i != ans)printf(" ") ;
}
printf("\n") ;
}
}

二分图专题总算告一段落了

感觉 现在只会抄模板了 ..

明天...哈理工的最菜的三个选手 我和带我飞我的两个队友要去勇闯ecfinal题了 祝自己好运 ...

[kuangbin带你飞]专题十 匹配问题 一般图匹配的更多相关文章

  1. [kuangbin带你飞]专题十 匹配问题

        A-L 二分匹配 M-O 二分图多重匹配 P-Q 二分图最大权匹配 R-S 一般图匹配带花树 模板请自己找     ID Origin Title   61 / 72 Problem A HD ...

  2. [kuangbin带你飞]专题十 匹配问题 二分匹配部分

    刚回到家 开了二分匹配专题 手握xyl模板 奋力写写写 终于写完了一群模板题 A hdu1045 对这个图进行 行列的重写 给每个位置赋予新的行列 使不能相互打到的位置 拥有不同的行与列 然后左行右列 ...

  3. [kuangbin带你飞]专题十 匹配问题 二分图多重匹配

    二分图的多重匹配问题不同于普通的最大匹配中的"每个点只能有最多一条边" 而是"每个点连接的边数不超过自己的限定数量" 最大匹配所解决的问题一般是"每个 ...

  4. [kuangbin带你飞]专题十 匹配问题 二分图最大权匹配

    二分图最大权匹配有km算法和网络流算法 km算法模板默认解决最大权匹配的问题 而使用最小费用最大流 是解决最小权匹配问题 这两种办法都可以求最大最小权 需要两次取反 TAT 感觉讲km会很难的样子.. ...

  5. [kuangbin带你飞]专题十五 数位DP

            ID Origin Title   62 / 175 Problem A CodeForces 55D Beautiful numbers   30 / 84 Problem B HD ...

  6. [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题解报告

    来刷kuangbin字符串了,字符串处理在ACM中是很重要的,一般比赛都会都1——2道有关字符串处理的题目,而且不会很难的那种,大多数时候都是用到一些KMP的性质或者找规律. 点击标题可跳转至VJ比赛 ...

  7. [kuangbin带你飞]专题十四 数论基础

            ID Origin Title   111 / 423 Problem A LightOJ 1370 Bi-shoe and Phi-shoe   21 / 74 Problem B ...

  8. 【算法系列学习】DP和滚动数组 [kuangbin带你飞]专题十二 基础DP1 A - Max Sum Plus Plus

    A - Max Sum Plus Plus https://vjudge.net/contest/68966#problem/A http://www.cnblogs.com/kuangbin/arc ...

  9. [kuangbin带你飞]专题十二 基础DP1

            ID Origin Title   167 / 465 Problem A HDU 1024 Max Sum Plus Plus   234 / 372 Problem B HDU 1 ...

随机推荐

  1. 在eclipse里面使用git仓库,并且使用maven加载项目

    前提:安装完成git和maven(maven需要在eclipse中配置完成) 1.点击Windows->show view 选择Git Repositories(git仓库) 2.点击2号图标, ...

  2. react native的环境搭建中常见问题

    搭建完成android的环境,我们就可以继续我们的react native环境的搭建了. 当然,按照fb的安装流程来完成rn的搭建. http://facebook.github.io/react-n ...

  3. eclipse下设置tomcat,修改Java代码不必重启tomcat

    1.本文目的:用tomcat进行web开发时,修改Java代码往往要重启代码,当工程较大启动较慢时,严重影响效率,本文通过eclipse下tomcat开发和发布web程序时,对一些Java代码一般修改 ...

  4. 通过spring boot提供restful api

    1 将返回设置为produces = "application/json" 返回给客户端json格式的response. 2 对各种异常的处理 各种异常如何返回给客户端? 各种异常 ...

  5. python系列一:python3基础语法

    '''python保留字即关键字,我们不能把它们用作任何标识符名称.Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字: '''>>> import ...

  6. spring和hibernate整合时设置自动生成数据库的表

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFa ...

  7. badboy脚本参数化和检查点

    一.badboy脚本参数化 文本参数化 方式一:直接在Variablesl ist添加参数化变量和值,然后在Script里面找到对应需要参数化的内容-属性,进行替换,参数化名需要用${XX}引用: 方 ...

  8. python并发之IO模型(二)

    blocking IO (阻塞IO) 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样: 当用户进程调用了recvfrom这个系统调用,kernel就开 ...

  9. git原理:pack打包

    git向磁盘中存储对象使用“松散(loose)”对象格式.比如文件a.txt第一个版本大小是10k,第二个版本向其中添加了一行代码,假如此时文件为10.1k,那么第二个版本会重新产生一个1.1k的文件 ...

  10. id函数

    描述 id() 函数用于获取对象的内存地址. 语法 id 语法: id([object]) 参数说明: object -- 对象. 返回值 返回对象的内存地址. 实例 以下实例展示了 id 的使用方法 ...