舞动的夜晚 CH Round #17

描述

L公司和H公司举办了一次联谊晚会。晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞。在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的,这样的认识关系一共有T对。舞会上,每位员工会尝试选择一名Ta认识的对方公司的员工作为舞伴,并且每位员工至多跳一支舞。完成的交际舞的数量越多,晚会的气氛就越热烈。顾及到晚会的气氛,员工们希望知道,哪些员工之间如果进行了交际舞,就会使整场晚会能够完成的交际舞的最大数量减小。

输入格式

第一行三个整数N、M、T。

接下来T行每行两个整数x、y,表示L公司的员工x和H公司的员工y互相认识。

输出格式

第一行一个整数cnt,表示进行了交际舞后会使整场晚会能够完成的交际舞的最大数量减小的员工有多少对。

第二行cnt个整数,升序输出这样的一hunyinhunyin对员工的认识关系的编号(他们的认识关系是在输入数据中读入的第几条认识关系)。如果cnt=0,输出一个空行。

样例输入

3 3 6
1 1
2 1
2 2
3 1
3 2
3 3

样例输出

3
2 4 5

数据范围与约定

  • 对于50%的数据,1<=N,M<=100,1<=T<=1000。
  • 对于100%的数据,1<=N,M<=10000,1<=T<=100000,1<=x<=N,1<=y<=M。

题解

二分图的不可行边——最大流+Tarjan

对于50%的数据,先求出最大匹配的值,然后枚举每一条边,连上之后重求最大匹配,看答案是否为原最大匹配-1。求最大匹配用匈牙利算法。

对于100%的数据,先用Dinic求任意一组最大匹配,然后建一张新图:

匹配边(i,j) j到i连边

非匹配边 (i,j) i到j连边

匹配的左点i (i,S)

不匹配的左点i (S,i)

匹配的右点j (T,j)

不匹配的右点j (j,T)

然后用Tarjan求强连通分量

(i,j)是可行边的条件:

(i,j)是匹配边 或者 i,j在同一个scc里

那么总边数减去可行边数就是不可行边数,即答案。

注意这个新图要包含源和汇,不能只在二分图两部之间连边,除非原最大匹配是一个完备匹配。

证明过程,写在书上了,很详细。

时间复杂度\(O(E\sqrt{N+M})\)


注意那个源汇点连边的时候,因为初始tot=1,所以枚举的是正边。

求出二分图最大匹配的不可行边板子题,使用 dinic 求最大流,tarjan 求强连通分量。

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3fffffff, u = 40010, w = 300010;
int head[u], ver[w], edge[w], Next[w], d[u], e[w], c[u], sta[u], ins[u], dfn[u], low[u];
int n, m, p, s, t, i, j, tot, maxflow, ans, x, y, scc, st, num;
char str[10];
vector<int> a[u];
queue<int> q; void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
} bool bfs() {
memset(d, 0, sizeof(d));
while (q.size()) q.pop();
q.push(s); d[s] = 1;
while (q.size()) {
int x = q.front(); q.pop();
for (int i = head[x]; i; i = Next[i])
if (edge[i] && !d[ver[i]]) {
q.push(ver[i]);
d[ver[i]] = d[x] + 1;
if (ver[i] == t) return 1;
}
}
return 0;
} int dinic(int x, int flow) {
if (x == t) return flow;
int rest = flow, k;
for (int i = head[x]; i && rest; i = Next[i])
if (edge[i] && d[ver[i]] == d[x] + 1) {
k = dinic(ver[i], min(rest, edge[i]));
if (!k) d[ver[i]] = 0;
edge[i] -= k;
edge[i ^ 1] += k;
rest -= k;
}
return flow - rest;
} void add2(int x, int y)
{
a[x].push_back(y);
} void tarjan(int x)
{
dfn[x] = ++num; low[x] = num;
sta[++st] = x; ins[x] = 1;
int y;
for (int i = 0; i<a[x].size(); i++)
if (!dfn[y = a[x][i]])
{
tarjan(y);
low[x] = min(low[x], low[y]);
}
else if (ins[y]) low[x] = min(low[x], dfn[y]);
if (dfn[x] == low[x])
{
scc++;
do { y = sta[st]; st--; ins[y] = 0; c[y] = scc; } while (x != y);
}
} int main()
{
while (cin >> n >> m >> p)
{
memset(head, 0, sizeof(head));
s = 0, t = n + m + 1; tot = 1; maxflow = 0;
for (i = 1; i <= n; i++) add(s, i, 1);
for (i = 1; i <= m; i++) add(i + n, t, 1);
for (i = 1; i <= p; i++)
{
scanf("%d%d", &x, &y);
add(x, n + y, 1), e[i] = tot;
}
while (bfs())
while (i = dinic(s, inf)) maxflow += i;
for (i = s; i <= t; i++) a[i].clear();
for (i = 1; i <= p; i++)
if (!edge[e[i]]) add2(ver[e[i]], ver[e[i] ^ 1]);
else add2(ver[e[i] ^ 1], ver[e[i]]);
for (i = 1; i <= n; i++)
if (!edge[2 * i]) add2(i, s); else add2(s, i);
for (i = 1; i <= m; i++)
if (!edge[2 * (n + i)]) add2(t, n + i); else add2(n + i, t);
memset(dfn, 0, sizeof(dfn));
memset(ins, 0, sizeof(ins));
memset(c, 0, sizeof(c));
st = num = scc = ans = 0;
for (i = s; i <= t; i++)
if (!dfn[i]) tarjan(i);
for (i = 1; i <= p; i++)
if (edge[e[i]] || c[ver[e[i]]] == c[ver[e[i] ^ 1]]) ans++;
cout << (ans = p - ans) << endl;
if (!ans) cout << endl;
for (i = 1; i <= p; i++)
if (!edge[e[i]] && c[ver[e[i]]] != c[ver[e[i] ^ 1]])
if (--ans) printf("%d ", i); else printf("%d\n", i);
}
return 0;
}

CH#17C 舞动的夜晚(最大流+强连通分量)的更多相关文章

  1. CH#17C 舞动的夜晚

    原题链接 即求二分图的不可行边数量,因为不保证是完备匹配,所以需要通过网络流求出任意一组最大匹配,并建立新图判断. 建新图:对于跑完网络流的图上已经匹配的边,建立反边:对于没有匹配的边,建立正边(图只 ...

  2. [Contest Hunter#17-C] 舞动的夜晚

    [题目链接] http://contest-hunter.org:83/contest/CH%20Round%20%2317/%E8%88%9E%E5%8A%A8%E7%9A%84%E5%A4%9C% ...

  3. ContestHunter#17-C 舞动的夜晚

    Description: L公司和H公司举办了一次联谊晚会.晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞.在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的,这样的认识关系一 ...

  4. CH Round #17 舞动的夜晚

    舞动的夜晚 CH Round #17 描述 L公司和H公司举办了一次联谊晚会.晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞.在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的 ...

  5. HAOI2017 新型城市化 二分图的最大独立集+最大流+强连通缩点

    题目链接(洛谷):https://www.luogu.org/problemnew/show/P3731 题意概述:给出一张二分图,询问删掉哪些边之后可以使这张二分图的最大独立集变大.N<=10 ...

  6. AcWing 380. 舞动的夜晚

    大型补档计划 题目链接 这题是求必须边,而不是不可行边,因为不可行边 = 必须边 + 死掉了的边(貌似lyd第三版书上还是说的不可行边)先跑最大流. 在跑完以后的残余网络上,对于一条当前匹配的边 \( ...

  7. Poj 1904 King's Quest 强连通分量

    题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...

  8. hdu 4685 二分匹配+强连通分量

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 题解: 这一题是poj 1904的加强版,poj 1904王子和公主的人数是一样多的,并且给出 ...

  9. BZOJ 1179 [Apio2009]Atm(强连通分量)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1179 [题目大意] 给出一张有向带环点权图,给出一些终点,在路径中同一个点的点权只能累 ...

  10. Kosaraju算法解析: 求解图的强连通分量

    Kosaraju算法解析: 求解图的强连通分量 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 定义 连通分量:在无向图中,即为连 ...

随机推荐

  1. 开源推荐,灵活多变功能强大的CMDB

    一个完善的基础资源数据库是我们构建运维自动化上层应用的基础,所以构建CMDB系统成了有想法在DevOps运维自动化领域有所发展的企业离不开的重要一环,但受制于每家企业不同的内外部环境.资源配置以及管理 ...

  2. 给大家介绍一款强大的抓包代理工具--mitmproxy

    最近工作中涉及到和app相关的测试工作,需要用到mock,特意网上查了些资料,发现有很多工具可以实现app的mock,但是经过我反复试用后,发现mitmproxy这个工具非常的强大 我认为mitmpr ...

  3. .NET8极致性能优化Non-GC Heap

    前言 .NET8里面JIT引入了一个新的机制,叫做Non-GC Heap.JIT可以确保相关对象分配在Non-GC Heap上,该堆像其名称一样,不受GC管理.JIT需要保证这个对象没有被GC引用,并 ...

  4. 神经网络入门篇:详解随机初始化(Random+Initialization)

    当训练神经网络时,权重随机初始化是很重要的.对于逻辑回归,把权重初始化为0当然也是可以的.但是对于一个神经网络,如果把权重或者参数都初始化为0,那么梯度下降将不会起作用. 来看看这是为什么. 有两个输 ...

  5. vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程

    这章我们讲回调,英文名:Beyond callbacks 一.章节覆盖: 回调函数及其限制,如网关/边缘服务示例所示 未来和承诺--链接异步操作的简单模型 响应式扩展--一个更强大的模型,特别适合组合 ...

  6. 网安靶场环境_DVWA-读取文件报错File not found! Cookie中有两个security键

    DVWA-文件包含漏洞-读取文件报错-ERROR: File not found! Cookie中有两个security键 1 问题复现 (1)登录DVMA后,设置DVWA Security为Low. ...

  7. JUC——让步与优先级

    Thread.yield():方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源),并执行其他线程 yield():做的是让当前运行线程回到可运行的状态,以允许具有相同优先级的其他线程 ...

  8. 9 "网址"--URI

    目录 URI和URL URI详细介绍 URI的组成 URI的查询参数 URI的编码 疑问 URI和URL URI:统一资源标识符(Uniform Resource Identifier) 有两种形式: ...

  9. 【UniApp】-uni-app-数据传递补充

    前言 好,经过上个章节的介绍完毕之后,了解了一下 uni-app-CompositionAPI传递数据 那么了解完了uni-app-CompositionAPI传递数据之后,这篇文章来给大家介绍一下 ...

  10. .NET开发中合理使用对象映射库,简化和提高工作效率

    前言 在日常开发中,我们常常需要将一个对象映射到另一个对象,这个过程中可能需要编写大量的重复性代码,如果每次都手动编写,不仅会影响开发效率,而且当项目越来越复杂,庞大的时候还容易出现错误.为了解决这个 ...