题意:

求不相交的最小路径覆盖

思路:

连边跑二分图,匹配一条边相当于缩了一条边,答案为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. keuectl命令

    Kubernetes命令行 kubectl用于运行Kubernetes集群命令的管理工具 kubectl命令行语法 kubectl [command] [TYPE] [NAME] [flags] co ...

  2. python常用英语单词(初学,英语不好的适用)

    对于刚才是学习python这些也足够了,一天学个六七个单词记一下在配合自己寻找的视频.书籍等等方法去学习是有一定帮助的. 这里还是要说一句,仅供兴趣爱好学习使用,个人开发者(非考虑未来靠此为生的人士) ...

  3. ArcEngine连接Oracle数据库

    问题1: 最近写服务需要用ArcEngine连接Oracle数据库,以前连接数据库都会弹出一个窗体.然后填好之后就可以连接了,这样很麻烦. 代码如下: private bool ConnectToSd ...

  4. 【Java编程思想阅读笔记】Java数据存储位置

    Java数据存储位置 P46页有感 一.前置知识 栈是由系统自动分配的,Java程序员对栈没有直接的操作权限, 堆是所有线程共享的内存区域,栈 是每个线程独享的. 堆是由程序员自己申请的,在使用new ...

  5. 【JavaScript 基础知识】一篇关于 JavaScript 一些知识点的总结

    JavaScript 中基础数据类型  数据类型名称  数据类型说明 Undefined 只有一个值,即 undefined ,声明变量的初始值. Null 只有一个值,即 null ,表示空指针,  ...

  6. CSS中设置元素的圆角矩形

    圆角矩形介绍 在CSS中通过border-radius属性可以实现元素的圆角矩形. border-radius属性值一共有4个,左上.右上.左下.右下. border-radius属性值规则如下:第一 ...

  7. Java入门 - 语言基础 - 20.Stream和File和IO

    原文地址:http://www.work100.net/training/java-stream-file-io.html 更多教程:光束云 - 免费课程 Stream和File和IO 序号 文内章节 ...

  8. [bzoj4569] [loj#2014] [Scoi2016] 萌萌哒

    Description 一个长度为 \(n\) 的大数,用 \(S1S2S3...Sn\) 表示,其中 \(Si\) 表示数的第 \(i\) 位, \(S1\) 是数的最高位,告诉你一些限制条件,每个 ...

  9. ps入门

    目标:把运动截图的日期改掉.一次运动,天天装逼! 1 左上角   文件 -> 打开  选中要P的图片 2 CRTL 和 +号  放大 3 摁住空格键就可以用鼠标拖动图片(把要P的部分放到中间) ...

  10. git使用的常见命令汇总

    git的简单介绍 git是分布式版本控制工具 git 的基本操作指令 git init 初始化git仓库 git add 文件名 git add . 把文件 添加到 git 暂存区中 git stat ...