CH#17C 舞动的夜晚(最大流+强连通分量)
舞动的夜晚 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 舞动的夜晚(最大流+强连通分量)的更多相关文章
- CH#17C 舞动的夜晚
原题链接 即求二分图的不可行边数量,因为不保证是完备匹配,所以需要通过网络流求出任意一组最大匹配,并建立新图判断. 建新图:对于跑完网络流的图上已经匹配的边,建立反边:对于没有匹配的边,建立正边(图只 ...
- [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% ...
- ContestHunter#17-C 舞动的夜晚
Description: L公司和H公司举办了一次联谊晚会.晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞.在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的,这样的认识关系一 ...
- CH Round #17 舞动的夜晚
舞动的夜晚 CH Round #17 描述 L公司和H公司举办了一次联谊晚会.晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞.在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的 ...
- HAOI2017 新型城市化 二分图的最大独立集+最大流+强连通缩点
题目链接(洛谷):https://www.luogu.org/problemnew/show/P3731 题意概述:给出一张二分图,询问删掉哪些边之后可以使这张二分图的最大独立集变大.N<=10 ...
- AcWing 380. 舞动的夜晚
大型补档计划 题目链接 这题是求必须边,而不是不可行边,因为不可行边 = 必须边 + 死掉了的边(貌似lyd第三版书上还是说的不可行边)先跑最大流. 在跑完以后的残余网络上,对于一条当前匹配的边 \( ...
- Poj 1904 King's Quest 强连通分量
题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...
- hdu 4685 二分匹配+强连通分量
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 题解: 这一题是poj 1904的加强版,poj 1904王子和公主的人数是一样多的,并且给出 ...
- BZOJ 1179 [Apio2009]Atm(强连通分量)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1179 [题目大意] 给出一张有向带环点权图,给出一些终点,在路径中同一个点的点权只能累 ...
- Kosaraju算法解析: 求解图的强连通分量
Kosaraju算法解析: 求解图的强连通分量 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 定义 连通分量:在无向图中,即为连 ...
随机推荐
- 4. Shell 循环语句
重点: 条件测试. read. Shell 环境配置. case. for. find. xargs. gzip,bzip2,xz. tar. sed. 1)循环 1.1)循环执行介绍 将某代码段重复 ...
- 【Javaweb】servlet一
什么是servlet 1.servlet是JavaEE规范之一,规范就是接口. 2.servlet是Javaweb三大组件之一.三大组件分别是:servlet程序.filter过滤器.listener ...
- VideoPipe可视化视频结构化框架更新总结(2023-12-5)
项目地址:https://github.com/sherlockchou86/video_pipe_c 往期文章:https://www.cnblogs.com/xiaozhi_5638/p/1696 ...
- C/C++ 实现动态资源文件释放
当我们开发Windows应用程序时,通常会涉及到使用资源(Resource)的情况.资源可以包括图标.位图.字符串等,它们以二进制形式嵌入到可执行文件中.在某些情况下,我们可能需要从可执行文件中提取自 ...
- idea用不了 idea.bat文件闪退
由于idea的智能,在破解之后会留下一些问题,根据网上搜出来的解决办法. 1.C:\Users\dell\AppData\Roaming\JetBrains\IntelliJIdea2022.2 在这 ...
- IoC入门案例
1.管理什么?(Service和Dao) 2.如何将被管理的对象告知IoC容器?(配置) 3.被管理的对象交给IoC容器,如何获取IoC容器?(接口) 4.IoC容器得到后,如何从容器中获取到bean ...
- StarBlog - 2023年底更新内容一览
前言 先说一下我对 StarBlog 这个系列的文章的规划吧,在 StarBlog 的 1.x 版本,我会同步更新两个系列的文章 博客前台+接口开发笔记 (即当前已发布的这一系列文章) 博客Vue后台 ...
- flask请求钩子(就是django的中间件)
flask中的请求钩子就是域django的中间件类似,作用都是用于在请求前.后.响应前.后进行一些hook操作. 请求钩子装饰器 @app.before_request # 请求前会调用,一般可以用来 ...
- 使用 PostgreSQL 16.1 + Citus 12.1 作为多个微服务的分布式 Sharding 存储后端
在本教程中,我们将使用 PostgreSQL 16.1 + Citus 12.1 作为多个微服务的存储后端,演示此类集群的样例设置和基本操作. Citus 12.1 实验环境设置 Docker 快速启 ...
- Charles的奇巧淫技
大家好,我是 dom 哥.今天讨论一下 Charles 的高级用法. Charles 是 mac 电脑的一个网络代理软件,也是我平时开发常用的一个工具,用过的都说好. 本文不是 Charles 的入门 ...