URAL1099 Work Scheduling —— 一般图匹配带花树
题目链接:https://vjudge.net/problem/URAL-1099
1099. Work Scheduling
Memory limit: 64 MB
Input
Output
Sample
| input | output |
|---|---|
3 |
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 —— 一般图匹配带花树的更多相关文章
- URAL 1099. Work Scheduling (一般图匹配带花树)
1099. Work Scheduling Time limit: 0.5 secondMemory limit: 64 MB There is certain amount of night gua ...
- kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树
二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...
- HDU 4687 Boke and Tsukkomi (一般图匹配带花树)
Boke and Tsukkomi Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Othe ...
- URAL1099. Work Scheduling(一般图匹配带花树开花算法)
1099. Work Scheduling Time limit: 0.5 second Memory limit: 64 MB There is certain amount of night gu ...
- HDU 4687 Boke and Tsukkomi 一般图匹配,带花树,思路,输出注意空行 难度:4
http://acm.hdu.edu.cn/showproblem.php?pid=4687 此题求哪些边在任何一般图极大匹配中都无用,对于任意一条边i,设i的两个端点分别为si,ti, 则任意一个极 ...
- HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力
一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...
- ZOJ 3316 Game 一般图最大匹配带花树
一般图最大匹配带花树: 建图后,计算最大匹配数. 假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点.后手不论怎么走,都必定走到一个被匹配的点上.先手就能够顺着这个交错路走下去,最后一定是后 ...
- 【learning】一般图最大匹配——带花树
问题描述 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...
- UOJ #79 一般图最大匹配 带花树
http://uoj.ac/problem/79 一般图和二分图的区别就是有奇环,带花树是在匈牙利算法的基础上对奇环进行缩点操作,复杂度似乎是O(mn)和匈牙利一样. 具体操作是一个一个点做类似匈牙利 ...
随机推荐
- luogu2261 [CQOI2007]余数求和
除法分块. 猜想: 记 \(g(x)=\lfloor k / \lfloor k / x\rfloor \rfloor\),则对于 \(i \in [x,g(x)]\),\(\lfloor k / i ...
- Javascript拼接HTML字符串的方法列举及思路
转载过来,去掉一些废话吧. 目标: 方便的拼接字符串,不使用让人眼晕的+=.使用过程如下: 1,先创建一个作为“模板”的字符串,如:’My name is ${name},I\’m ${age}.’ ...
- JavaEE JDBC 了解数据库连接池
了解数据库连接池 @author ixenos 数据库连接是有限的资源,如果用户需要离开应用一段时间,那么他占用的连接就不应该保持开放状态: 另一方面,每次查询都获取连接并在随后关闭它的代价也很高. ...
- 【dfs+理解题意+构造】【待重做】codeforces E. Ice cream coloring
http://codeforces.com/contest/805/problem/E [题意] 染色数是很好确定,最少染色数是max(si)(最小为1,即使所有的si都为0,这样是单节点树形成的森林 ...
- 【multimap的应用】D. Array Division
http://codeforces.com/contest/808/problem/D #include<iostream> #include<cstdio> #include ...
- java中filter的用法
filter过滤器主要使用于前台向后台传递数据是的过滤操作.程度很简单就不说明了,直接给几个已经写好的代码: 一.使浏览器不缓存页面的过滤器 Java代码 import javax.servlet ...
- 【Ural1297】Palindrome(后缀数组)
题意:求一个字符串的最长回文子串 n<=1000 思路:这是一道论文题 需要注意的细节: 1.奇偶分类 2.中间的分割符与最后的附加字母都是最小值,但两者不能相同,否则height可能会出现问题 ...
- POJ3150:Cellular Automaton
题意看不懂加题目想不通,很菜. n<=500个数围城环,每次操作对每个数Ai把与i在环上相距不超过d<n/2(包括Ai)的数加起来取模m<=1e6,求K<=1e7次操作后的环. ...
- msp430入门编程41
msp430中C语言的软件工程--状态机建模
- iOS 用cornerstone 创建分支
第一步:在cornerstone中添加服务器上的代码路径,如下: 第二步:选中服务器路径下的代码,选择“分支”按钮 第三步:开始创建分支 第四步:效果图如下 第五步:选择分支下的路径下载代码并进行修改 ...