题意:

求不相交的最小路径覆盖

思路:

连边跑二分图,匹配一条边相当于缩了一条边,答案为n-maxflow

如果是求可以相交的最小路径覆盖的话,先用Floyd跑出可达矩阵,然后所有可达的点连边跑二分图即可

代码:

这个dinic板子加边前要tot=1,否则每一对正反向流会乱掉

由于本题要输出方案,这里有两份代码,一份是跑最大流的时候记录流向,另一份是根据残余网络纪录流向

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <vector>
#include <ctime>
#include <map> #define fst first
#define sc second
#define pb push_back
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, mid, root << 1
#define rson mid + 1, r, root << 1 | 1
#define lc root << 1
#define rc root << 1 | 1
#define lowbit(x) ((x) & (-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PI;
typedef pair<ll, ll> PLL; const db eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 4e4 + ;
const int maxm = 4e5 + ;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int head[maxn], d[maxn]; //层
int ver[maxm], edge[maxm], Next[maxm]; // edge[i]: c for edge_i
int n, m, s, t, tot, maxflow;
queue<int> q;
int st[maxn];
void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
st[tot]=x;
ver[++tot] = x, edge[tot] = , Next[tot] = head[y], head[y] = tot;
st[tot]=y;
}
int du[maxn];
bool bfs() {
mem(d, );
while (!q.empty()) q.pop();
q.push(s);
d[s] = ;
while (!q.empty()) {
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] + ;
if (ver[i] == t)
return true;
}
}
}
return false;
}
int nx[maxn];
int dinic(int x, int flow) {
if (x == t)
return flow;
int rest = flow, k;
for (int i = head[x]; i; i = Next[i]) {
if (edge[i] && d[ver[i]] == d[x] + ) {
k = dinic(ver[i], min(rest, edge[i]));
if (!k) {
d[ver[i]] = ;
} else {
edge[i] -= k;
edge[i ^ ] += k;
rest -= k;
}
}
}
return flow - rest;
}
int vis[maxn];
int pre[maxn];
int main() {
mem(pre, -);
mem(nx,-);
s = ;
t = ;
tot = ;
scanf("%d %d", &n, &m);
for (int i = ; i <= m; i++) {
int x, y;
scanf("%d %d", &x, &y);
x *= ;
y *= ;
add(x, y + , );
}
for (int i = ; i <= n; i++) {
add(s, i * , );
add(i * + , t, );
}
int maxflow = ;
int flow;
while (bfs()) {
while () {
flow = dinic(s, inf);
if (flow == )
break;
maxflow += flow;
}
}
for(int i = ; i <= tot; i++){
if(edge[i]==&&st[i]%==&&st[i]>=&&st[i]<=*n&&ver[i]!=s){
int x = st[i]/;
int y = (ver[i]-)/;
//printf("%d %d\n",x,y);
pre[y] = x;
nx[x] = y;
}
}
for(int i = ; i <= n; i++){
if(pre[i]==-){
int x = i;
while(x!=-){
printf("%d ", x);
x= nx[x];
}
printf("\n");
}
}
printf("%d\n", n - maxflow);
return ;
} /*
5 3
1 2 3 4 5
1 2 3
2 1 4
4 3 5
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <vector>
#include <ctime>
#include <map> #define fst first
#define sc second
#define pb push_back
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, mid, root << 1
#define rson mid + 1, r, root << 1 | 1
#define lc root << 1
#define rc root << 1 | 1
#define lowbit(x) ((x) & (-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PI;
typedef pair<ll, ll> PLL; const db eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 4e2 + ;
const int maxm = 4e5 + ;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int head[maxn], d[maxn]; //层
int ver[maxm], edge[maxm], Next[maxm]; // edge[i]: c for edge_i
int n, m, s, t, tot, maxflow;
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] = , Next[tot] = head[y], head[y] = tot;
}
int du[maxn];
bool bfs() {
mem(d, );
while (!q.empty()) q.pop();
q.push(s);
d[s] = ;
while (!q.empty()) {
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] + ;
if (ver[i] == t)
return true;
}
}
}
return false;
}
int nx[maxn];
int dinic(int x, int flow) {
if (x == t)
return flow;
int rest = flow, k;
for (int i = head[x]; i; i = Next[i]) {
if (edge[i] && d[ver[i]] == d[x] + ) {
k = dinic(ver[i], min(rest, edge[i]));
if (!k) {
d[ver[i]] = ;
} else {
nx[x] = ver[i];
edge[i] -= k;
edge[i ^ ] += k;
rest -= k;
}
}
}
return flow - rest;
}
int vis[maxn];
int pre[maxn];
int main() {
mem(pre, -);
s = ;
t = ;
tot = ;
scanf("%d %d", &n, &m);
for (int i = ; i <= m; i++) {
int x, y;
scanf("%d %d", &x, &y);
x *= ;
y *= ;
add(x, y + , );
}
for (int i = ; i <= n; i++) {
add(s, i * , );
add(i * + , t, );
}
int maxflow = ;
int flow;
while (bfs()) {
while () {
flow = dinic(s, inf);
if (flow == )
break;
maxflow += flow;
}
}
for (int i = ; i <= n; i++) {
pre[(nx[i * ] - ) / ] = i;
} for (int i = ; i <= n; i++) {
if (vis[i])
continue;
if (pre[i] == -) {
int x = i;
while (x) {
vis[x] = ;
printf("%d ", x);
x = (nx[x * ] - ) / ;
}
printf("\n");
}
}
printf("%d\n", n - maxflow);
return ;
} /*
5 3
1 2 3 4 5
1 2 3
2 1 4
4 3 5
*/

Loj 6002 最小路径覆盖(最大流)的更多相关文章

  1. LibreOJ 6002 最小路径覆盖(最大流)

    题解:最小路径覆盖=总点数减去最大匹配数,拆点,按照每条边前一个点连源点,后一个点连汇点跑最大流,即可跑出最大匹配数,然后减一减就可以了~ 代码如下: #include<queue> #i ...

  2. [SDOI2010][bzoj1927] 星际竞速 [最小路径覆盖+费用流]

    题面 传送门 思路 仔细观察题目要求的东西,发现就是求一个最小路径覆盖,只不过可以跳跃(就是那个鬼畜的超级跳跃) 那么就直接上最小路径覆盖模版 对每个点,拆成两个点$X_i$和$Y_i$,建立超级源超 ...

  3. 洛谷 P2764 LibreOJ 6002 最小路径覆盖问题

    题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...

  4. 网络流24题 第三题 - CodeVS1904 洛谷2764 最小路径覆盖问题 有向无环图最小路径覆盖 最大流 二分图匹配 匈牙利算法

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - CodeVS1904 题目传送门 - 洛谷2764 题意概括 给出一个有向无环图,现在请你求一些路径,这些路径 ...

  5. Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)

    Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...

  6. [LOJ#6002]「网络流 24 题」最小路径覆盖

    [LOJ#6002]「网络流 24 题」最小路径覆盖 试题描述 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交)的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是  ...

  7. 【刷题】LOJ 6002 「网络流 24 题」最小路径覆盖

    题目描述 给定有向图 \(G = (V, E)\) .设 \(P\) 是 \(G\) 的一个简单路(顶点不相交)的集合.如果 \(V\) 中每个顶点恰好在 \(P\) 的一条路上,则称 \(P\) 是 ...

  8. LibreOJ #6002. 「网络流 24 题」最小路径覆盖

    #6002. 「网络流 24 题」最小路径覆盖 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...

  9. 【wikioi】1904 最小路径覆盖问题(最大流+坑人的题+最小路径覆盖)

    http://wikioi.com/problem/1904/ 这题没看数据的话是一个大坑(我已报告官方修复了),答案只要求数量,不用打印路径...orz 最小路径覆盖=n-最大匹配,这个我在说二分图 ...

随机推荐

  1. Huffman树及其编码(STL array实现)

    这篇随笔主要是Huffman编码,构建哈夫曼树有各种各样的实现方法,如优先队列,数组构成的树等,但本质都是堆. 这里我用数组来存储数据,以堆的思想来构建一个哈弗曼树,并存入vector中,进而实现哈夫 ...

  2. sqlserver 存储过程调Api接口

    --开启Sql Server 通讯配置-- sp_configure ; GO RECONFIGURE; GO sp_configure ; GO RECONFIGURE; GO EXEC sp_co ...

  3. java小项目之:象棋,羡慕你们有对象的!

    象棋,是我国传统棋类益智游戏,在中国有着悠久的历史,属于二人对抗性游戏的一种,由于用具简单,趣味性强,成为流行极为广泛的棋艺活动.中国象棋是中国棋文化也是中华民族的文化瑰宝. 象棋还有很多口诀,这是最 ...

  4. 【一起学源码-微服务】Eureka+Ribbon+Feign阶段性总结

    前言 想说的话 这里已经梳理完Eureka.Ribbon.Feign三大组件的基本原理了,今天做一个总结,里面会有一个比较详细的调用关系流程图. 说明 原创不易,如若转载 请标明来源! 博客地址:一枝 ...

  5. 【记】VirtualBox安装CentOS6

    推荐随笔 VirtualBox中安装CentOS-6.6虚拟机 问题1: 在选择虚拟硬盘大小时,最好不要用默认的8G 我的分区 /boot 200M swap 1024M /home 4096M / ...

  6. Jenkins-正则表达式提取Cookie

    场景描述:用户登录查询数据:登录时响应头返回Cookie,将Cookie使用正则表达式提取出来,在下一个请求“查询数据”时,在请求头中使用此Cookie 1.添加“登录”http请求 2.在后置处理器 ...

  7. kaggle预测房价的代码步骤

    # -*- coding: utf-8 -*- """ Created on Sat Oct 20 14:03:05 2018 @author: 12958 " ...

  8. KMP——强大的next数组

    \(KMP\) 的原理不在这里仔细讲了,主要说说最近刷题总结出的 \(next\) 数组的强大功能. 部分例题来自<信息学奥赛一本通>的配套练习. 基于定义--字符串相同前后缀 " ...

  9. EFCore-脚手架Scaffold发生Build Failed问题的终极解决

    大家在使用EntityFrameworkCore的DBFirst的脚手架(Scaffolding)时应该遇到过Build Failed的错误,而没有任何提示,我也遇到过不少次,目前已经完美解决并将排查 ...

  10. python类型-序列-元组

    元组是一种不可变类型,元组可用作一个字典的key. 1.创建一个元组并进行赋值 atuple = (123, 'abc', ('inner', 'tuple'), 7-9j) 2.访问元组中的值 元组 ...