Loj 6002 最小路径覆盖(最大流)
题意:
求不相交的最小路径覆盖
思路:
连边跑二分图,匹配一条边相当于缩了一条边,答案为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 最小路径覆盖(最大流)的更多相关文章
- LibreOJ 6002 最小路径覆盖(最大流)
题解:最小路径覆盖=总点数减去最大匹配数,拆点,按照每条边前一个点连源点,后一个点连汇点跑最大流,即可跑出最大匹配数,然后减一减就可以了~ 代码如下: #include<queue> #i ...
- [SDOI2010][bzoj1927] 星际竞速 [最小路径覆盖+费用流]
题面 传送门 思路 仔细观察题目要求的东西,发现就是求一个最小路径覆盖,只不过可以跳跃(就是那个鬼畜的超级跳跃) 那么就直接上最小路径覆盖模版 对每个点,拆成两个点$X_i$和$Y_i$,建立超级源超 ...
- 洛谷 P2764 LibreOJ 6002 最小路径覆盖问题
题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...
- 网络流24题 第三题 - CodeVS1904 洛谷2764 最小路径覆盖问题 有向无环图最小路径覆盖 最大流 二分图匹配 匈牙利算法
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - CodeVS1904 题目传送门 - 洛谷2764 题意概括 给出一个有向无环图,现在请你求一些路径,这些路径 ...
- Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)
Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...
- [LOJ#6002]「网络流 24 题」最小路径覆盖
[LOJ#6002]「网络流 24 题」最小路径覆盖 试题描述 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交)的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是 ...
- 【刷题】LOJ 6002 「网络流 24 题」最小路径覆盖
题目描述 给定有向图 \(G = (V, E)\) .设 \(P\) 是 \(G\) 的一个简单路(顶点不相交)的集合.如果 \(V\) 中每个顶点恰好在 \(P\) 的一条路上,则称 \(P\) 是 ...
- LibreOJ #6002. 「网络流 24 题」最小路径覆盖
#6002. 「网络流 24 题」最小路径覆盖 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...
- 【wikioi】1904 最小路径覆盖问题(最大流+坑人的题+最小路径覆盖)
http://wikioi.com/problem/1904/ 这题没看数据的话是一个大坑(我已报告官方修复了),答案只要求数量,不用打印路径...orz 最小路径覆盖=n-最大匹配,这个我在说二分图 ...
随机推荐
- Pandas常用方法手册
关键缩写和包导入 在这个速查手册中,我们使用如下缩写: df:任意的Pandas DataFrame对象 同时我们需要做如下的引入: import pandas as pd 导入数据 pd.read_ ...
- 我与Git的那些破事--代码管理实践
1. Git是什么? 作为一名程序猿,我相信大家都或多或少接触过git--分布式版本控制软件. 有人说,它是目前世界上最先进的分布式版本控制系统,我想说,是否最先进不知道,但确实好用,实用. 作为一款 ...
- Excel获取当前日期和时间
在Excel中获取当前时间 1.第一种在空的单元格内输入函数“NOW()”回车即可获取当前时间如图 2.第二种选中空单元格“按住CTRL+:”回车即可获取当前时间 3.第一种在空的单元格内输入函数“t ...
- (01)大话设计模式-简单工厂-java实现
1.运算接口 public interface Operation { public double getResult(double NumberA , double NumberB); } 2.加减 ...
- JVM之堆的体系结构
一.堆的体系结构 Heap 堆一个JVM 实例只存在一个堆内存,堆内存的大小是可以调节的.类加载器读取了类字节码文件后,需要把类.方法.常量.变最放到堆内存中,保存所有引用类型的真实信息,以便执行器执 ...
- mongodb学习(一)——简介和基本操作
简介 MongoDB 是一个基于分布式文件存储的数据库 属于NoSQL数据库,是介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的 旨在为WEB应用提供可扩展的高性 ...
- 最新IDEA永久激活攻略
前言 写这篇文章的原因是我最近想自己写两个项目,却发现自己的IDEA过期了,对,就是那个JAVA编辑器,于是研究了一下IDEA的激活.发现网上的攻略大多数不可用. 当然这里推荐大家去官网购买正版使用. ...
- await Task.Yield(); 超简单理解!
上面的代码类似于: Task.Run(() => { }).ContinueWith(t => Do(LoadData())); 意思就是: loadData 如果耗时较长那么上述代码会产 ...
- Jetbrains CLion 安装及配置详解
# Hi 今天呢就给大家推荐一个高大上 强大智能的 C/C++语言编辑器.ta的名字叫-- Jetbrains CLion (呃,说好了不用标题字呢) 这个编辑器呢主要支持C和C ++,包括现代C + ...
- 18个Java8日期处理的实践,对于程序员太有用了!
18个Java8日期处理的实践,对于程序员太有用了! Java 8 推出了全新的日期时间API,在教程中我们将通过一些简单的实例来学习如何使用新API. Java处理日期.日历和时间的方式一直为社区所 ...