大型补档计划

题目链接

这题是求必须边,而不是不可行边,因为不可行边 = 必须边 + 死掉了的边(貌似lyd第三版书上还是说的不可行边)先跑最大流。

在跑完以后的残余网络上,对于一条当前匹配的边 \((u, v)\),对应流量为 \(1\),只有他们有可能是必须边。

考虑断开这条边,能否找到增广路,如果能就是可行边,否则是必须边。

新的增广路的端点一定是 \(u, v\) 中的一个,否则即有更大的最大流。

接下来分类讨论。

  1. 若是找到一条 (u, v) 的路径且不包括 t,则可以把增广路上的边全部取反,就得到了一组新的答案。

  2. 若是一个点 u 找到了它的非匹配点 z, 由于 \(w(z, t) = 1, w(t, v) = 0\),所以 \((u, v)\) 还是构成一个环,包括 t

如果两点都不满足,必然不成环,所以就用 tarjan 算法缩点以后判断在不在一个强连通分量即可。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 20005, S = 400005, INF = 1e9;
int n, m, T, s, t, q[N], d[N];
int dfn[N], low[N], dfncnt;
int col[N], cnt = 0, st[N], top;
bool ins[N];
struct E{
int next, v, w;
} e[S];
int head[N], numE = 1;
void inline add(int u, int v, int w) {
e[++numE] = (E) { head[u], v, w };
head[u] = numE;
}
bool bfs() {
memset(d, 0, sizeof d);
int hh = 0, tt = 0;
q[0] = s; d[s] = 1;
while (hh <= tt) {
int u = q[hh++];
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (e[i].w && !d[v]) {
d[v] = d[u] + 1;
q[++tt] = v;
if (v == t) return true;
}
}
}
return false;
}
int dinic(int u, int flow) {
if (u == t) return flow;
int rest = flow;
for (int i = head[u]; i && rest; i = e[i].next) {
int v = e[i].v;
if (e[i].w && d[v] == d[u] + 1) {
int k = dinic(v, min(rest, e[i].w));
if (!k) d[v] = 0;
e[i].w -= k, e[i ^ 1].w += k;
rest -= k;
}
}
return flow - rest;
}
bool tarjan(int u) {
dfn[u] = low[u] = ++dfncnt;
ins[u] = true, st[++top] = u;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (!e[i].w) continue;
if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
else if (ins[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
int v; ++cnt;
do {
v = st[top--];
ins[v] = false;
col[v] = cnt;
} while (v != u);
}
}
int main() {
scanf("%d%d%d", &n, &m, &T);
s = n + m + 1, t = n + m + 2;
for (int i = 1, u, v; i <= T; i++) {
scanf("%d%d", &u, &v);
add(u, v + n, 1); add(v + n, u, 0);
}
for (int i = 1; i <= n; i++) add(s, i, 1), add(i, s, 0);
for (int i = 1; i <= m; i++) add(n + i, t, 1), add(t, n + i, 0);
while (bfs() && dinic(s, INF));
for (int i = 1; i <= t; i++)
if (!dfn[i]) tarjan(i);
int ans = 0;
for (int i = 2; i <= 2 * T; i += 2)
if (e[i].w && col[e[i].v] != col[e[i ^ 1].v]) ans++;
printf("%d\n", ans);
if (!ans) puts("");
for (int i = 2; i <= 2 * T; i += 2)
if (e[i].w && col[e[i].v] != col[e[i ^ 1].v]) printf("%d ", i >> 1); }

AcWing 380. 舞动的夜晚的更多相关文章

  1. CH Round #17 舞动的夜晚

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

  2. CH#17C 舞动的夜晚

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

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

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

  4. [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% ...

  5. 二分图&网络流初步

    链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...

  6. 0x6A 网络流初步

    CH Round #17-C 这个算是一个技能点吧,不点不会,点了就没什么了.懒得写看书吧书上的1应该是0... 我又回来了太懒了不想翻书还是写写吧 必须边的判定条件:该边流量为0且两端的点在残余网络 ...

  7. [考试反思]1019csp-s模拟测试80(a):天遣

    A组题,所以把榜粘全了. 第6名,被卡在刚好正中间. 我最近干什么伤天害理的事了?(例如说没有在skyh去上厕所的时候捶他) 上来看T1,非常贴心出题人直接把递推式子给你了,然后就和斐波数的递推一样了 ...

  8. Noip模拟58 2021.9.21(中秋祭&&换机房祭)

    第一次在学校过中秋节,给家里人视频电话,感觉快回家了很开心, 然后还吃了汉堡喝饮料非常爽,颓废了一会儿还换了新机房,$Linux2.0$非常dei,少爷机也非常快, 发现好像测评机又成了老爷机,这就是 ...

  9. 2021.9.21考试总结[NOIP模拟58]

    T1 lesson5! 开始以为是个无向图,直接不懂,跳去T2了. 之后有看了一眼发现可暴力,于是有了\(80pts\). 发现这个图是有拓扑序的,于是可以用拓扑排序找最长路径.先找原图内在最长路径上 ...

随机推荐

  1. 阻塞队列的take、offer、put、add的一些比较

    LinkedBlockingQueue的put,add和offer的区别 最近在学习<<Java并发编程实践>>,有很多java.util.concurrent包下的新类.Li ...

  2. linux组管理(groupadd/groupmod/gpasswd/groupdel)

    配置文件:  /etc/group 注:用户组(group)配置文件: /etc/gshadow 注:用户组(group)的影子文件: 查看组: cat /etc/group  或者  id -g t ...

  3. WPF窗体中嵌入/使用WinForm类/控件(基于.NET Core)

    如题,WPF中嵌入WinForm的做法,网络上已经很多示例,都是基于.NET XXX版的. 今天King様在尝试WPF(基于.NET Core 3.1)中加入Windows.Forms.ColorDi ...

  4. webpack 无法打包:No configuration file found and no output filename configured via CLI option

    报错内容 No configuration file found and no output filename configured via CLI option.A configuration fi ...

  5. MongoDB动态建表方案(官方原生驱动)

    MongoDB动态建表方案(官方原生驱动) 需求前提:表名动态,表结构静态,库固定 1.导入相关依赖 <dependency> <groupId>org.mongodb< ...

  6. 面试阿里,腾讯,字节跳动90%都会被问到的Spring中的循环依赖

    前言 Spring中的循环依赖一直是Spring中一个很重要的话题,一方面是因为源码中为了解决循环依赖做了很多处理,另外一方面是因为面试的时候,如果问到Spring中比较高阶的问题,那么循环依赖必定逃 ...

  7. Java(8)I/O

    目录 一.File类 1.File类概述 2.File类实例化 3.File类常用方法 二.IO流的原理 1.IO流的原理 2.input和output的理解 三.IO流的分类 1.分类 2.图示 3 ...

  8. Python学习系列之列表(十一)

    一.为什么需要列表 变量可以存储一个元素,而列表是一个"大容器"可以存储N多个元素,程序可以方便地对这些数据进行整体操作 列表相当于其它语言中的数组 二.列表的创建1.列表需要使用 ...

  9. Codeforces Round #668 C. Balanced Bitstring (Div. 2)题解(思维)

    题目链接 题目大意 给你一个长为n的01串,要你使得每一个01串中0和1的个数都要相等,01串中有?字符,你可以使得这个字符变为0或1,要你求是否可以满足条件.输出YES或NO 题目思路 这个题目的难 ...

  10. 经典算法—BF算法(字符串匹配)

    前言 字符串的匹配算法也是很经典的一个算法,在面试的时候常常会遇到,而BF算法是字符串模式匹配中的一个简单的算法 1,什么是BF算法 BF算法,即暴力(Brute Force)算法,是普通的模式匹配算 ...