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-最大匹配,这个我在说二分图 ...
随机推荐
- centos7.3安装chrome
Centos7安装chrome浏览器 1.配置yum源 在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repo cd /ect/yum.repos.d/ vim ...
- 利用Python进行数据分析学习记录(一)
1.Python的科学计算邮件列表 pydata:这是一个Google Group邮件列表,其中的问题都是Python数据分析和pandas方面的. pystatsmodels:针对Numpy相关的问 ...
- 【转】8 个效果惊人的 WebGL/JavaScript 演示
英文原文:9 IMPRESSIVE WEBGL JAVASCRIPT EFFECT SHOWCASE,翻译:iteye WebGL 是一种 3D 绘图标准,这种绘图技术标准允许把 JavaScript ...
- ip转十进制(PHP、MySQL)
mysql与php中都提供了IP转换十进制数函数 1. IP 由点分格式,转换为数字格式,代码如下: mysql> select inet_aton('127.0.0.1'); +------- ...
- 第7节class与style绑定
方法一 效果图: 方法二 效果图: 方法三 效果图: 代码: <!DOCTYPE html> <html lang="en" xmlns:v-bind=&qu ...
- Microsoft Visual Studio提示正忙如何解决
打开项目的时候会一直提示正在加载,然后卡死,点击VS界面即出现下如图- 如图: 解决方法: 1.打开项目 找到一个叫vs的文件夹, 2.找到一个后缀是.suo的文件 把它删掉 3.关闭VS进程 重新打 ...
- Nginx在Centos 7中配置开机启动
1.创建脚本 # vi /etc/init.d/nginx #!/bin/bash # nginx Startup script for the Nginx HTTP Server # it is v ...
- 清晰架构(Clean Architecture)的Go微服务: 事物管理
为了支持业务层中的事务,我试图在Go中查找类似Spring的声明式事务管理,但是没找到,所以我决定自己写一个. 事务很容易在Go中实现,但很难做到正确地实现. 需求: 将业务逻辑与事务代码分开. 在编 ...
- springboot下Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
已检查jar包是否引入 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId ...
- Collections中的常用方法
collections中的常用方法 public class CollectionsTest { public static void main(String[] args) { List list ...