[kuangbin带你飞]专题十 匹配问题 一般图匹配
过去做的都是二分图匹配 即 同一个集合里的点 互相不联通
但是如果延伸到一般图上去 求一个一般图的最大匹配 就要用带花树来解决
带花树模板 用来处理一个无向图上的最大匹配
看了一会还是不懂 抄了一遍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带你飞]专题十 匹配问题 一般图匹配的更多相关文章
- [kuangbin带你飞]专题十 匹配问题
A-L 二分匹配 M-O 二分图多重匹配 P-Q 二分图最大权匹配 R-S 一般图匹配带花树 模板请自己找 ID Origin Title 61 / 72 Problem A HD ...
- [kuangbin带你飞]专题十 匹配问题 二分匹配部分
刚回到家 开了二分匹配专题 手握xyl模板 奋力写写写 终于写完了一群模板题 A hdu1045 对这个图进行 行列的重写 给每个位置赋予新的行列 使不能相互打到的位置 拥有不同的行与列 然后左行右列 ...
- [kuangbin带你飞]专题十 匹配问题 二分图多重匹配
二分图的多重匹配问题不同于普通的最大匹配中的"每个点只能有最多一条边" 而是"每个点连接的边数不超过自己的限定数量" 最大匹配所解决的问题一般是"每个 ...
- [kuangbin带你飞]专题十 匹配问题 二分图最大权匹配
二分图最大权匹配有km算法和网络流算法 km算法模板默认解决最大权匹配的问题 而使用最小费用最大流 是解决最小权匹配问题 这两种办法都可以求最大最小权 需要两次取反 TAT 感觉讲km会很难的样子.. ...
- [kuangbin带你飞]专题十五 数位DP
ID Origin Title 62 / 175 Problem A CodeForces 55D Beautiful numbers 30 / 84 Problem B HD ...
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题解报告
来刷kuangbin字符串了,字符串处理在ACM中是很重要的,一般比赛都会都1——2道有关字符串处理的题目,而且不会很难的那种,大多数时候都是用到一些KMP的性质或者找规律. 点击标题可跳转至VJ比赛 ...
- [kuangbin带你飞]专题十四 数论基础
ID Origin Title 111 / 423 Problem A LightOJ 1370 Bi-shoe and Phi-shoe 21 / 74 Problem B ...
- 【算法系列学习】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 ...
- [kuangbin带你飞]专题十二 基础DP1
ID Origin Title 167 / 465 Problem A HDU 1024 Max Sum Plus Plus 234 / 372 Problem B HDU 1 ...
随机推荐
- PowerDesigner之设置(3)——根据Name首字母生成Code
SQL版本:2000 PowerDesigner版本:16 网上有不少介绍 PowerDesigner Name/Code自动调整 的文章,但基本如出一辙. 这里,我就介绍下如何根据输入的Name根据 ...
- 数据库几种连接方式的(左右union all)
A表 id name 1 bai 2 zhang 3 li B表 a_id score 1 80 2 70 1 30 左连接: select A.* ,B.* from A a left outer ...
- 是面向对象设计五个基本原则(SOLID)
单一职责原则 - 搜狗百科 https://baike.sogou.com/v51360965.htm 单一职责原则并不是一个孤立的面向对象设计原则,它是面向对象设计五个基本原则(SOLID)之一.这 ...
- [转载]在table上使用::before/::after的问题
在table上使用::before/::after的问题 转载自: 次碳酸钴的技术博客 http://www.web-tinker.com/article/20638.html 在table上使用:: ...
- Thinking In Myself
what is the I want to be? you know yourself? what is your dream? your interest? your passion? why y ...
- Wicket:一种构建和测试动态 Web 页面的简化框架
https://www.ibm.com/developerworks/cn/web/wa-aj-wicket/
- [String ] StringBuffer VS StringBuilder
StringBuilder的性能高于StringBuffer,因为StringBuffer是线程安全的. 首先说明一下,一般情况下,字符串相加默认是StringBuilder,但是当数量大于100,或 ...
- cqlsh script
1.time类型 cqlsh> COPY my_keyspace.typetest from STDIN;Using 1 child processes Starting copy of my_ ...
- Python之函数2 嵌套,作用域和闭包(Day12)
一.函数对象 1.函数是第一类对象,即函数可以当做数据传递 1.1 可以被引用 1.2 可以当做参数传递 1.3 返回值可以是函数 1.4 可以当做容器类型的元素 二.函数的嵌套 1.函数嵌套的调用: ...
- UI控件之UINavigationController
ViewController1 *vc1=[[ViewController1 alloc]init]; UINavigationController *nav1=[[UINavigationContr ...