P2764 最小路径覆盖问题
题目描述
«问题描述:
给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。设计一个有效算法求一个有向无环图G 的最小路径覆盖。提示:设V={1,2,.... ,n},构造网络G1=(V1,E1)如下:

每条边的容量均为1。求网络G1的( 0 x , 0 y )最大流。
«编程任务:
对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。
输入输出格式
输入格式:
件第1 行有2个正整数n和m。n是给定有向无环图G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。
输出格式:
从第1 行开始,每行输出一条路径。文件的最后一行是最少路径数。
输入输出样例
11 12
1 2
1 3
1 4
2 5
3 6
4 7
5 8
6 9
7 10
8 11
9 11
10 11
1 4 7 10 11
2 5 8
3 6 9
3 这题是一个网络流常用模型,
最小路径覆盖问题;
这题反向思考,就是点的数目-最大的二分匹配;
就是最少的路径数目;
这题算出最小路径,直接套网络流模板就行了;
但是要输出路径这就很恶心了;
我放弃了我自己原来的网络流模板;
找了一个更加适合输出路径的代码;
输出路径真心恶心
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 0x3fffffff
using namespace std;
const int maxn = 1e5 + ;
int head[maxn], sign, cur[maxn];
int s, t, d[maxn];
struct node {
int to, w, next;
} edge[maxn] ;
void creat() {
memset(head, -, sizeof(head));
sign = ;
}
void add(int u, int v, int w) {
edge[sign].to = v;
edge[sign].w = w;
edge[sign].next = head[u];
head[u] = sign++;
edge[sign].to = u;
edge[sign].w = ;
edge[sign].next = head[v];
head[v] = sign++;
}
int bfs() {
queue<int>q;
memset(d, , sizeof(d));
d[s] = ;
q.push(s);
while(!q.empty()) {
int top = q.front();
q.pop();
for (int i = head[top] ; ~i ; i = edge[i].next ) {
int to = edge[i].to;
if (edge[i].w > && d[to] == ) {
d[to] = d[top] + ;
if (to == t) return ;
q.push(to);
}
}
}
return d[t] != ;
}
int dfs(int top, int flow ) {
if (top == t) return flow;
int ans = , x = ;
for (int i = cur[top] ; ~i ; i = edge[i].next) {
int to = edge[i].to;
if (edge[i].w > && d[to] == d[top] + ) {
x = dfs(to, min(flow - ans, edge[i].w)) ;
edge[i].w -= x;
edge[i ^ ].w += x;
if (edge[i].w) cur[top] = i;
ans += x;
if (ans == flow) return flow;
}
}
if (ans == ) return d[top] = ;
return ans;
} int dinic(int n) {
int ans = ;
while(bfs()) {
for (int i = ; i <= n ; i++)
cur[i] = head[i];
ans += dfs(s, inf);
}
return ans;
}
int n, m, vis[maxn];
void go(int x, int &f) {
int loc = x + n;
vis[x] = ;
for (int i = head[loc] ; ~i ; i = edge[i].next)
if (edge[i].w == && edge[i].to != n * + ) go(edge[i].to, f) ;
if (f == ) f = ;
printf(" ");
printf("%d", x);
}
int main() {
scanf("%d%d", &n, &m);
creat();
s = , t = * n + ;
for (int i = ; i <= n ; i++)
add(s, i, ), add(i + n, t, );
int x, y;
while(m--) {
scanf("%d%d", &x, &y);
add(x, y + n, );
}
int ans = n - dinic(t);
for (int i = head[t]; ~i ; i = edge[i].next) {
if (edge[i].w == && !vis[edge[i].to - n]) {
int f = ;
go(edge[i].to - n, f);
printf("\n");
}
}
printf("%d\n", ans);
return ;
}
P2764 最小路径覆盖问题的更多相关文章
- 洛谷 P2764 最小路径覆盖问题 解题报告
P2764 最小路径覆盖问题 问题描述: 给定有向图\(G=(V,E)\).设\(P\) 是\(G\) 的一个简单路(顶点不相交)的集合.如果\(V\) 中每个顶点恰好在\(P\) 的一条路上,则称\ ...
- Luogu P2764 最小路径覆盖问题(二分图匹配)
P2764 最小路径覆盖问题 题面 题目描述 «问题描述: 给定有向图 \(G=(V,E)\) .设 \(P\) 是 \(G\) 的一个简单路(顶点不相交)的集合.如果 \(V\) 中每个顶点恰好在 ...
- P2764 最小路径覆盖问题 网络流重温
P2764 最小路径覆盖问题 这个题目之前第一次做的时候感觉很难,现在好多了,主要是二分图定理不太记得了,二分图定理 知道这个之后就很好写了,首先我们对每一个点进行拆点,拆完点之后就是跑最大流,求出最 ...
- 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】
题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...
- 网络流二十四题之P2764 最小路径覆盖问题
题目描述 给定有向图 G=(V,E)G=(V,E) .设 PP 是 GG 的一个简单路(顶点不相交)的集合.如果 VV 中每个定点恰好在PP的一条路上,则称 PP 是 GG 的一个路径覆盖.PP中路径 ...
- 洛谷P2764 最小路径覆盖问题
有向无环图的最小路径点覆盖 最小路径覆盖就是给定一张DAG,要求用尽量少的不相交的简单路径,覆盖有向无环图的所有顶点. 有定理:顶点数-路径数=被覆盖的边数. 要理解的话可以从两个方向: 假设DAG已 ...
- P2764 最小路径覆盖问题(网络流24题之一)
题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...
- 【刷题】洛谷 P2764 最小路径覆盖问题
题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...
- 洛谷P2764 最小路径覆盖问题(最大流)
传送门 先说做法:把原图拆成一个二分图,每一个点被拆成$A_i,B_i$,若原图中存在边$(u,v)$,则连边$(A_u,B_v)$,然后$S$对所有$A$连边,所有$B$对$T$连边,然后跑一个最大 ...
- luogu P2764 最小路径覆盖问题
题目描述 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开始,长度也是任 ...
随机推荐
- u-boot.bin生成过程分析
ELF格式“u-boot”文件的生成规则如下,下面对应Makefile的执行过程分别分析各个依赖. $(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $( ...
- (数据科学学习手札18)二次判别分析的原理简介&Python与R实现
上一篇我们介绍了Fisher线性判别分析的原理及实现,而在判别分析中还有一个很重要的分支叫做二次判别,本文就对二次判别进行介绍: 二次判别属于距离判别法中的内容,以两总体距离判别法为例,对总体G1,, ...
- R语言学习笔记(十四):零碎知识点(41-45)
41--ls( ) ls()可以用来列出现存的所有对象. pattern是一个具名参数,可以列出所有名称中含有字符串"s"的对象. > ls() [1] "s&qu ...
- ABAP CDS ON HANA-(10)項目結合して一つ項目として表示
Numeric Functions ABS(arg) CEIL(arg) DIV(arg1, arg2) DIVISION(arg1, arg2, dec) FLOOR(arg) MOD(arg1, ...
- HBase java API 的使用范例(增,删,查,扫描)
编辑pom.xml <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase ...
- 初步学习pg_control文件之十一
接前文 初步学习pg_control文件之十,再看这个 XLogRecPtr prevCheckPoint; /* previous check point record ptr */ 发生了che ...
- 【问题记录】Linux Python等交互式输入回退键出现 ^H^H
执行:yum install readline readline-devel
- 创龙DSP6748开发板SYS/BIOS的LED闪烁-第2篇
1. 作为1个456MHz的处理器,不跑个操作系统说不过去,直接打开工程\Demo\SYSBIOS\Application\GPIO_LED,主函数比较简单 // 创建任务 Task_create(t ...
- Excel拼接字符串
有时候,需要把一些Excel表格中的内容进行拼接,比如A4行的值是前面三行值的加起来.在Excel中可以使用&来进行这种操作.如果数据非常多,就可以使用这个来进行批量操作.
- oracle 认识
有一家叫甲骨文的粮店,老板很严谨,为了防止仓库的粮食在买入卖出的时候发生问题,他制订一套流程,首先进出仓库的每一旦粮食都要求有一个编号(SCN),而且出入库之前必须先放到一个平台上(buffer ca ...