一般图最大匹配带花树+暴力:

先算最大匹配 C1

在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2

假设C2+2==C1则这条边再某个最大匹配中

Boke and Tsukkomi

Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)

Total Submission(s): 649    Accepted Submission(s): 202

Problem Description
A new season of Touhou M-1 Grand Prix is approaching. Girls in Gensokyo cannot wait for participating it. Before the registration, they have to decide which combination they are going to compete as. Every girl in Gensokyo is both a boke (funny girl) and a tsukkomi
(straight girl). Every candidate combination is made up of two girls, a boke and a tsukkomi. A girl may belong to zero or more candidate combinations, but one can only register as a member of one formal combination. The host of Touhou M-1 Grand Prix hopes
that as many formal combinations as possible can participate in this year. Under these constraints, some candidate combinations are actually redundant as it\'s impossible to register it as a formal one as long as the number of formal combinations has to be
maximized. So they want to figure out these redundant combinations and stop considering about them.

 
Input
There are multiple test cases. Process to the End of File.

The first line of each test case contains two integers: 1 ≤ N ≤ 40 and 1 ≤ M ≤ 123, where N is the number of girls in Gensokyo, and M is the number of candidate combinations. The following M lines are M candidate combinations, one by each line.
Each combination is represented by two integers, the index of the boke girl 1 ≤ Bi ≤ N and the index of the tsukkomi girl 1 ≤ Ti ≤ N, where Bi != Ti.
 
Output
For each test case, output the number of redundant combinations in the first line. Then output the space-separated indexes of the redundant combinations in ascending order in the second line.
 
Sample Input
4 4
1 3
2 3
2 4
3 1
6 6
1 2
3 2
3 4
5 2
5 4
5 6
 
Sample Output
1
2
3
2 4 5
 
Author
Zejun Wu (watashi)
 
Source
 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector> using namespace std; const int maxn=50; vector<int> ans; bool G[maxn][maxn],TG[maxn][maxn]; int n,m;
int Match[maxn];
int Start,Finish,NewBase;
int Father[maxn],Base[maxn];
bool InQueue[maxn],InPath[maxn],InBlossom[maxn];
int Count;
queue<int> q; int FindCommonAncestor(int u,int v)
{
memset(InPath,false,sizeof(InPath));
while(true)
{
u=Base[u];
InPath[u]=true;
if(u==Start) break;
u=Father[Match[u]];
}
while(true)
{
v=Base[v];
if(InPath[v]) break;
v=Father[Match[v]];
}
return v;
} void ResetTrace(int u)
{
int v;
while(Base[u]!=NewBase)
{
v=Match[u];
InBlossom[Base[u]]=InBlossom[Base[v]]=true;
u=Father[v];
if(Base[u]!=NewBase) Father[u]=v;
}
} void BlossomContract(int u,int v)
{
NewBase=FindCommonAncestor(u,v);
memset(InBlossom,false,sizeof(InBlossom));
ResetTrace(u); ResetTrace(v);
if(Base[u]!=NewBase) Father[u]=v;
if(Base[v]!=NewBase) Father[v]=u;
for(int tu=1;tu<=n;tu++)
{
if(InBlossom[Base[tu]])
{
Base[tu]=NewBase;
if(!InQueue[tu])
{
q.push(tu);
InQueue[tu]=true;
}
}
}
} void FindAugmentingPath()
{
memset(InQueue,false,sizeof(InQueue));
memset(Father,0,sizeof(Father));
for(int i=1;i<=n;i++)
Base[i]=i;
while(!q.empty()) q.pop();
q.push(Start); InQueue[Start]=true;
Finish=0; while(!q.empty())
{
int u=q.front(); q.pop();
InQueue[u]=false;
for(int i=1;i<=n;i++)
{
if(i==u||G[u][i]==false) continue;
int v=i;
if(Base[u]!=Base[v]&&Match[u]!=v)
{
if(v==Start||(Match[v]>0&&Father[Match[v]]>0))
BlossomContract(u,v);
else if(Father[v]==0)
{
Father[v]=u;
if(Match[v]>0)
{
q.push(Match[v]);
InQueue[Match[v]]=true;
}
else
{
Finish=v;
return ;
}
}
}
}
}
} void AugmentPath()
{
int u,v,w;
u=Finish;
while(u>0)
{
v=Father[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)
{
Start=u;
FindAugmentingPath();
if(Finish>0) AugmentPath();
}
}
} int bian[200][2]; int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(G,0,sizeof(G));
memset(TG,0,sizeof(TG));
ans.clear(); for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
bian[i][0]=u;bian[i][1]=v;
G[u][v]=G[v][u]=1;
TG[u][v]=TG[v][u]=1;
} Edmonds(); Count=0;
for(int i=1;i<=n;i++)
if(Match[i]) Count++; for(int i=0;i<m;i++)
{
int u=bian[i][0],v=bian[i][1];
///clear about u,v
for(int j=1;j<=n;j++)
{
G[u][j]=G[j][u]=G[j][v]=G[v][j]=0;
} Edmonds(); int C2=0;
for(int j=1;j<=n;j++)
if(Match[j]) C2++; if(C2<Count-2)
ans.push_back(i+1); ///Recover
for(int j=1;j<=n;j++)
{
G[u][j]=TG[u][j]; G[j][u]=TG[j][u];
G[v][j]=TG[v][j]; G[j][v]=TG[j][v];
}
}
int sz = ans.size();
printf("%d\n",sz);
for(int i=0;i<sz;i++)
{
printf("%d",ans[i]);
if(i<sz-1)printf(" ");
}
printf("\n");
}
return 0;
}

HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力的更多相关文章

  1. HDU 4687 Boke and Tsukkomi 一般图匹配,带花树,思路,输出注意空行 难度:4

    http://acm.hdu.edu.cn/showproblem.php?pid=4687 此题求哪些边在任何一般图极大匹配中都无用,对于任意一条边i,设i的两个端点分别为si,ti, 则任意一个极 ...

  2. HDU 4687 Boke and Tsukkomi (一般图最大匹配)【带花树】

    <题目链接> 题目大意: 给你n个点和m条边,每条边代表两点具有匹配关系,问你有多少对匹配是冗余的. 解题分析: 所谓不冗余,自然就是这对匹配关系处于最大匹配中,即该匹配关系有意义.那怎样 ...

  3. ZOJ 3316 Game 一般图最大匹配带花树

    一般图最大匹配带花树: 建图后,计算最大匹配数. 假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点.后手不论怎么走,都必定走到一个被匹配的点上.先手就能够顺着这个交错路走下去,最后一定是后 ...

  4. 【learning】一般图最大匹配——带花树

    问题描述 ​ 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...

  5. UOJ #79 一般图最大匹配 带花树

    http://uoj.ac/problem/79 一般图和二分图的区别就是有奇环,带花树是在匈牙利算法的基础上对奇环进行缩点操作,复杂度似乎是O(mn)和匈牙利一样. 具体操作是一个一个点做类似匈牙利 ...

  6. 【UOJ 79】 一般图最大匹配 (✿带花树开花)

    从前一个和谐的班级,所有人都是搞OI的.有 n 个是男生,有 0 个是女生.男生编号分别为 1,…,n. 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人负责吐槽.每个人至多属于 ...

  7. 【UOJ #79】一般图最大匹配 带花树模板

    http://uoj.ac/problem/79 带花树模板,做法详见cyb的论文或fhq的博客. 带花树每次对一个未盖点bfs增广,遇到奇环就用并查集缩环变成花(一个点),同时记录每个点的Next( ...

  8. HDU 4687 Boke and Tsukkomi (一般图匹配带花树)

    Boke and Tsukkomi Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Othe ...

  9. kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

    二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...

随机推荐

  1. vc++远程调试工具

    简单来说: 1>在远程机器跑VC自带的远程调试工具msvsmon.exe,并把要调试的程序跑起来 2>用VC调试器附加进程,即可调试 先展开来说: VC8,VC9都自带远程调试工具,可以在 ...

  2. jQuery 自学笔记—8 常见操作

    jQuery 拥有可操作 HTML 元素和属性的强大方法. jQuery DOM 操作 jQuery 中非常重要的部分,就是操作 DOM 的能力. jQuery 提供一系列与 DOM 相关的方法,这使 ...

  3. 表空间的状态(二) - read/write

    表空间状态-READ ONLY.READ WRITE 1. 仅仅读表空间的主要用途就是为了消除对数据库大部分静态数据的备份和恢复的须要.Oracle不会更新仅仅读表空间爱你的文件.因此这部分文件能够存 ...

  4. Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记

    第一章 Thread导论 为何要用Thread ? 非堵塞I/O      I/O多路技术      轮询(polling)      信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...

  5. 齐博软件(地方门户系统) 文件加密破解工具

    原文:齐博软件(地方门户系统) 文件加密破解工具 本程序为针对"齐博软件地方门户系统5.0官方原版"的破解工具,一个垃圾系统居然弄出这么恶心的加密方式,有个鸟用!以后见一个破一个! ...

  6. javascript面向对象程序设计

    在学习js面向对象编程之前,首先须要知道什么是面向对象.面向对象语言都有类的概念,通过它能够创建具有同样属性和方法的对象.但js并没有类的概念,因此js中的对象和其它语言的对象有所不同. js对象能够 ...

  7. DL动态载入框架技术文档

    DL动态载入框架技术文档 DL技术交流群:215680213 1. Android apk动态载入机制的研究 2. Android apk动态载入机制的研究(二):资源载入和activity生命周期管 ...

  8. IBM之MQ使用指南

    随着计算机网络和分布式应用的不断发展.远程消息传递越来越成为应用系统中必不可少的组成部分. 商业消息中间件的出现保证了消息传输的可靠性,高效率和安全性,同一时候也降低了系统的开发周期. 眼下应用最多的 ...

  9. ubuntu/linux mint 创建proc文件的三种方法(两)

    在这样做的内核驱动程序的开发时间.可以使用/proc下档.获取相应的信息.对于调试. 大多数/proc下的文件是仅仅读的.但为了演示样例的完整性.都提供了写方法. 方法一:使用create_proc_ ...

  10. c#控制台应用程序-“进入指定日期检查出星期几”

    这涉及一个算法: 基姆拉尔森计算公式 W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1) mod 7 在公式中d表示日期中的日数.m表示月份数.y表示年数. 注意:在公式 ...