题目链接:https://vjudge.net/problem/URAL-1099

1099. Work Scheduling

Time limit: 0.5 second
Memory limit: 64 MB
There is a certain amount of night guards that are available to protect the local junkyard from possible junk robberies. These guards need to be scheduled in pairs so that each pair guards in a different night. The junkyard CEO ordered you to write a program which given the guards characteristics determines the maximum amount of scheduled guards (the rest will be fired). Please note that each guard can be scheduled with only one of his colleagues and no guard can work alone.

Input

The first line of the input contains one number N ≤ 222 which is a number of night guards. Unlimited number of lines consisting of unordered pairs (ij) follow, each such pair means that guard #i and guard #j can work together, because it is possible to find uniforms that suit both of them (The junkyard uses different parts of uniforms for different guards i.e. helmets, pants, jackets. It is impossible to put small helmet on a guard with a big head or big shoes on guard with small feet). The input ends with Eof.

Output

You should output one possible optimal assignment. On the first line of the output write the even number C, the amount of scheduled guards. Then output C/2 lines, each containing 2 integers (ij) that denote that i and j will work together.

Sample

input output
3
1 2
2 3
1 3
2
1 2

题解:

一般图匹配带花树的模板题。还是看不太懂,以后有时间再看看。

有关怎么找到奇环:

其中可以把最右边两个点看成是找到奇环时的两个点,其中root为他们的LCA。

疑问1:什么要把花上的边的方向取反?

疑问2:为什么在找奇环时要特判 v==start ?

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
const int INF = 2e9;
const int MOD = 1e9+;
const int MAXM = +;
const int MAXN = 2e3+; int N;
bool graph[MAXN][MAXN];
int match[MAXN];
bool inque[MAXN], inpath[MAXN], inblos[MAXN];
queue<int>q;
int start, finish;
int newbase, fa[MAXN], base[MAXN]; int FindCommonAncester(int u, int v) //仅仅是找LCA,并不修改任何值
{
memset(inpath, false, sizeof(inpath));
while(true)
{
u = base[u];
inpath[u] = true;
if(u==start) break;
u = fa[match[u]];
}
while(true)
{
v = base[v];
if(inpath[v]) break;
v = fa[match[v]];
}
return v;
} void ResetTrace(int u) //把fa的方向取反
{
int v;
while(base[u]!=newbase) //匹配边、非匹配边交替出现
{
v = match[u]; //u--match[u]匹配边
inblos[base[u]] = inblos[base[v]] = true;
u = fa[v]; //v--fa[v]非匹配边
if(base[u]!=newbase) fa[u] = v;
}
} void BloosomContract(int u, int v)
{
newbase = FindCommonAncester(u, v);
memset(inblos, false, sizeof(inblos));
ResetTrace(u); //把u到LCA上的边取反
ResetTrace(v); //把v到LCA上的边取反
if(base[u]!=newbase) fa[u] = v; //看不懂
if(base[v]!=newbase) fa[v] = u; for(int tu = ; tu<=N; tu++)
if(inblos[base[tu]])
{
base[tu] = newbase; //设置它属于的集合
if(!inque[tu]) q.push(tu); //在花中的点加入队列,因为与花中点相连的点还可以找增广路
}
} void FindAugmentingPath()
{
memset(inque, false, sizeof(inque));
memset(fa, , sizeof(fa));
for(int i = ; i<=N; i++)
base[i] = i;
while(!q.empty()) q.pop();
q.push(start);
finish = ; while(!q.empty())
{
int u = q.front(); q.pop(); for(int v = ; v<=N; v++) //fa[u]--u是匹配边, u--v是未匹配边。
if(graph[u][v] && base[u]!=base[v] && match[u]!=v )
{
//为什么要特判 v==start ?
if( (v==start) || (match[v]> && fa[match[v]]>)) //找到奇环。
BloosomContract(u, v);
else if(fa[v]==) //v点在这次找增广路时没有被访问
{
fa[v] = u;
if(match[v]>) //如果已经匹配了,则加入他的匹配点,继续找增广路。
q.push(match[v]);
else //如果没有匹配,则找到了增广路。
{
finish = v;
return;
}
}
}
}
} void AugmentPath()
{
int u, v, w;
u = finish;
while(u>) //沿着增广路往回走,把匹配边和非匹配边取反
{
v = fa[u];
w = match[v];
match[v] = u;
match[u] = v;
u = w;
}
} void Edmonds()
{
memset(match, , sizeof(match));
for(int u = ; u<=N; u++)
if(match[u]==)
{
start = u;
FindAugmentingPath();
if(finish>) AugmentPath();
}
} int main()
{
scanf("%d", &N);
memset(graph, false, sizeof(graph));
int u, v;
while(scanf("%d%d", &u, &v)!=EOF)
graph[u][v] = graph[v][u] = true; Edmonds();
int sum = ;
for(int u = ; u<=N; u++)
if(match[u]>) sum++;
printf("%d\n", sum);
for(int u = ; u<=N; u++)
if(u<match[u])
printf("%d %d\n", u, match[u]); return ;
}

URAL1099 Work Scheduling —— 一般图匹配带花树的更多相关文章

  1. URAL 1099. Work Scheduling (一般图匹配带花树)

    1099. Work Scheduling Time limit: 0.5 secondMemory limit: 64 MB There is certain amount of night gua ...

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

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

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

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

  4. URAL1099. Work Scheduling(一般图匹配带花树开花算法)

    1099. Work Scheduling Time limit: 0.5 second Memory limit: 64 MB There is certain amount of night gu ...

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

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

  6. HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力

    一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...

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

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

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

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

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

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

随机推荐

  1. 大数据学习——hdfs集群启动

    第一种方式: 1 格式化namecode(是对namecode进行格式化) hdfs namenode -format(或者是hadoop namenode -format) 进入 cd /root/ ...

  2. spring的IOC入门案例

    步骤: 一,导入jar 二,创建类,在类里创建方法 三,创建Spring配置文件,配置创建类 四,写代码测试对象创建

  3. 内置函数--map,filter,reduce

    一.map class map(object): """ map(func, *iterables) --> map object Make an iterator ...

  4. 洛谷 P 1018 乘积最大 ==Codevs

    题目描述 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得 ...

  5. CF778A:String Game

    给出字符串s和t,以及s的长度n的一个全排列,求按照这个排列依次删除s的字符,删到何时s中不含子序列t. 解法一: t中的每个字符的位置在s中跳啊跳,合法的情况下t中的字符在s中的位置应该是单调递增的 ...

  6. vagrant的学习 之 Laravel

    vagrant的学习 之 Laravel 本文根据慕课网的视频教程练习,感谢慕课网! 慕课视频学习地址:https://www.imooc.com/video/14218. 慕课的参考文档地址:htt ...

  7. XCode warning:“View Controller” is unreachable because it has no entry points

    Unsupported Configuration: “View Controller” is unreachable because it has no entry points, and no i ...

  8. Xcode warning:Auto property synthesis will not synthesize property

    iOS 警告提示如下: 添加 @dynamic告诉编译器这个属性是动态的,动态的意思是等你编译的时候就知道了它只在本类合成; 如下:

  9. Unique Paths II (dp题)

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  10. CF723E(欧拉回路)

    题意: 给出一个有向图,要求给每条边重定向,使得定向后出度等于入度的点最多,输出答案和任意一种方案. 分析: 将图看作无向图,对每条边重定向 首先我们肯定分成多个连通分量来考虑,每一个连通分量都是一个 ...