题目描述

«问题描述:

给定有向图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 行开始,每行输出一条路径。文件的最后一行是最少路径数。

输入输出样例

输入样例#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: 复制

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 最小路径覆盖问题的更多相关文章

  1. 洛谷 P2764 最小路径覆盖问题 解题报告

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

  2. Luogu P2764 最小路径覆盖问题(二分图匹配)

    P2764 最小路径覆盖问题 题面 题目描述 «问题描述: 给定有向图 \(G=(V,E)\) .设 \(P\) 是 \(G\) 的一个简单路(顶点不相交)的集合.如果 \(V\) 中每个顶点恰好在 ...

  3. P2764 最小路径覆盖问题 网络流重温

    P2764 最小路径覆盖问题 这个题目之前第一次做的时候感觉很难,现在好多了,主要是二分图定理不太记得了,二分图定理 知道这个之后就很好写了,首先我们对每一个点进行拆点,拆完点之后就是跑最大流,求出最 ...

  4. 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】

    题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...

  5. 网络流二十四题之P2764 最小路径覆盖问题

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

  6. 洛谷P2764 最小路径覆盖问题

    有向无环图的最小路径点覆盖 最小路径覆盖就是给定一张DAG,要求用尽量少的不相交的简单路径,覆盖有向无环图的所有顶点. 有定理:顶点数-路径数=被覆盖的边数. 要理解的话可以从两个方向: 假设DAG已 ...

  7. P2764 最小路径覆盖问题(网络流24题之一)

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

  8. 【刷题】洛谷 P2764 最小路径覆盖问题

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

  9. 洛谷P2764 最小路径覆盖问题(最大流)

    传送门 先说做法:把原图拆成一个二分图,每一个点被拆成$A_i,B_i$,若原图中存在边$(u,v)$,则连边$(A_u,B_v)$,然后$S$对所有$A$连边,所有$B$对$T$连边,然后跑一个最大 ...

  10. luogu P2764 最小路径覆盖问题

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

随机推荐

  1. STL——map和set

    一.map 1.map被定义为一对(pair即key和value)数值. key值在map内最多只有一份. 假如需要对一篇文章中的单词计数,那么就可以建立一个map,string类型的key,int型 ...

  2. go学习笔记-包处理

    包处理 package是go管理代码的重要工具,用于组织 Go 源代码,提供了更好的可重用性与可读性. 可见性 变量或函数名的首字母大写时,其就是可导出的,小写时则是不可导出的. 函数和变量的可访问性 ...

  3. SQL数据库 面试题

    一.sql理论题 1.触发器的作用? 答:触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的.它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化. ...

  4. VINS紧耦合优化公式及代码解析

    1.首先确定待优化的状态变量 对应代码,优化参数为: Vector3d Ps[(WINDOW_SIZE + )];(平移向量) Vector3d Vs[(WINDOW_SIZE + )];(速度) M ...

  5. 一次和别人争吵一个按钮,点击后显示导航;再点击不显示的效果,是否一定以及必须用js?

    事情经过是这样的,我们组一个说话很喜欢用一定,肯定的哥们,吃午饭的时候拿了自己做的一个UI库,头部有一个按钮 点击展开,再次点击收缩,他意思说一个按钮无法记录点击状态,必须使用js.然后我看了一眼,心 ...

  6. 签名APK后仍然出现INSTALL_PARSE_FAILED_NO_CERTIFICATES的解决方案

    修改apk里的dex并且修复后重新打包进apk里,使用signapk.jar签名后安装仍然出现INSTALL_PARSE_FAILED_NO_CERTIFICATES,搜了很久,使用了多种方法签名仍然 ...

  7. Python-学习-小例子练习

    网上了点小例子,练习一下下,都是特别简单的.而且这些代码也都是找的网上的代码,目的是在于练习一下Python和熟悉下Python的编码风格等等 学习一门语言,最快的方法就是把它用在世界的开发中,这样才 ...

  8. NMON记录服务器各项性能数据

    1.将下载下来的nmon文件通过ftp传入服务器下,将nmon权限全开chmod +x nmon 2.查看nmon可以看到如下内容 查看各项指标 输入C,CPU数据 M,内存 N,网络 D,磁盘 T, ...

  9. 阿里云SLB上http强制跳转到https问题处理

    背景: 最近一客户有一个需求,需要将外网所有http访问请求强制跳转到https,公网出口使用阿里云SLB,证书放在SLB上,SLB后端实例为ECS(webserver)web服务使用nginx, 网 ...

  10. LeetCode 81——搜索旋转排序数组 II

    1. 题目 2. 解答 2.1. 方法一 基于 LeetCode 33--搜索旋转排序数组 中的方法二. 当 nums[mid] = nums[right] 时,比如 [1, 1, 2, 1, 1], ...