洛谷 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
说明
1<=n<=150,1<=m<=6000
由@FlierKing提供SPJ
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 #define INF 0x3f3f3f3f 10 const int maxn = 6e4+10; 11 int n,m,s,t,u,v; 12 struct Edge { 13 int from, to, cap, flow; 14 }; 15 vector<Edge> edges; 16 vector<int> G[maxn]; 17 bool vis[maxn]; 18 int d[maxn], cur[maxn],nxt[maxn]; 19 20 void Init() 21 { 22 memset(d,0,sizeof d); 23 for(int i=0;i<=2*n+1;i++) G[i].clear(); 24 } 25 26 void AddEdge(int from, int to, int cap) 27 { 28 edges.push_back((Edge){from, to, cap, 0}); 29 edges.push_back((Edge){to, from, 0, 0}); 30 int m = edges.size(); 31 G[from].push_back(m-2); G[to].push_back(m-1); 32 } 33 34 bool bfs() 35 { 36 memset(vis,0,sizeof vis); 37 queue<int> q; 38 q.push(s); 39 d[s] = 0; vis[s] = 1; 40 while (!q.empty()) 41 { 42 int x = q.front(); q.pop(); 43 for(int i = 0; i < G[x].size(); ++i) 44 { 45 Edge &e = edges[G[x][i]]; 46 if (!vis[e.to] && e.cap > e.flow) 47 { 48 vis[e.to] = 1; 49 d[e.to] = d[x] + 1; 50 q.push(e.to); 51 } 52 } 53 } 54 return vis[t]; 55 } 56 57 int dfs(int x,int a) 58 { 59 if(x == t || a == 0) return a; 60 int flow = 0, f; 61 for(int &i = cur[x]; i < G[x].size(); ++i) 62 { 63 Edge &e = edges[G[x][i]]; 64 if (d[e.to] == d[x] + 1 && (f=dfs(e.to, min(a, e.cap-e.flow))) > 0) 65 { 66 e.flow += f; 67 edges[G[x][i]^1].flow -= f; 68 flow += f; a -= f; 69 if (a == 0) break; 70 } 71 } 72 return flow; 73 } 74 75 int MaxFlow(int s, int t) 76 { 77 int flow = 0; 78 while (bfs()) 79 { 80 memset(cur,0,sizeof cur); 81 flow += dfs(s, INF); 82 } 83 return flow; 84 } 85 86 int main() 87 { 88 while(scanf("%d%d",&n,&m)!=EOF) 89 { 90 Init(); 91 for(int i=1;i<=m;i++) 92 { 93 scanf("%d%d",&u,&v); 94 AddEdge(u,v+n,1); 95 } 96 s=0,t=2*n+1; 97 for(int i=1;i<=n;i++) 98 { 99 AddEdge(s,i,1); 100 AddEdge(i+n,t,1); 101 } 102 int ans=MaxFlow(s,t); 103 memset(nxt,0,sizeof nxt); 104 memset(vis,0,sizeof vis); 105 106 for(int i=1;i<=n;i++) 107 { 108 for(int j=0;j<G[i].size();j++) 109 { 110 Edge &e=edges[G[i][j]]; 111 if(e.flow>0) nxt[e.from]=e.to-n; 112 } 113 } 114 for(int i=1;i<=n;i++) 115 { 116 if(!vis[i]) 117 { 118 int a=i; 119 vis[a]=1; 120 printf("%d",a); 121 while(nxt[a]) 122 { 123 a=nxt[a]; 124 vis[a]=1; 125 printf(" %d",a); 126 } 127 printf("\n"); 128 } 129 } 130 printf("%d\n",n-ans); 131 } 132 return 0; 133 }
View Code
转载于:https://www.cnblogs.com/songorz/p/9526588.html
洛谷 P2764(最小路径覆盖=节点数-最大匹配)相关推荐
- 洛谷 - P2764 最小路径覆盖问题(最大流+二分图最小路径覆盖+路径打印)
题目链接:点击查看 题目大意:给出一个由n个点和m条边组成的有向无环图,现在需要我们求最少可以将n个点分为多少条简单路径,并打印出每一条路径 题目分析:题意挺难懂的..简单来说就是让求二分图最小路径覆 ...
- P2764 最小路径覆盖问题(网络流)
P2764 最小路径覆盖问题 最小链覆盖问题,关键在于怎么转化为网络流问题,我们可以发现网络流的常见套路就是将一个点拆成出点和入点来处理,对于一条链恰好满足出点和入点匹配的性质,所以可以拆点然后对应连 ...
- LUOGU P2764 最小路径覆盖问题 (最小路径点覆盖)
解题思路 有向图最小路径点覆盖问题,有这样的结论就是有向图最小路径点覆盖等于n-拆点二分图中最大匹配.具体怎么证明不太知道..输出方案时找到所有左部未匹配的点一直走$match$就行了. #incl ...
- (hdu step 6.3.3)Air Raid(最小路径覆盖:求用最少边把全部的顶点都覆盖)
题目: Air Raid Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- hlg1492盒子【最小路径覆盖】
大意:有n个盒子,告诉你一些嵌套关系,比如a能放到b里 c能放到a里 问最少使多少盒子露在外面 分析:这里要求的是最少DAG的数量,也就是传说中的最小路径覆盖问题 最小路径覆盖: 公式:最小路径覆盖 ...
- 1350 Taxi Cab Scheme DAG最小路径覆盖
对于什么是DAG最小路径覆盖以及解题方法在我的另外的博客已经有了.http://www.cnblogs.com/Potato-lover/p/3980470.html 此题的题意: 公交车(出租车)车 ...
- HDU 3861 The King’s Problem (强连通缩点+DAG最小路径覆盖)
<题目链接> 题目大意: 一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.所有点只能属于一块区域:2,如果两点相互可达,则这两点必然要属于同一区域:3,区域内任意两点 ...
- HDU 3861 The King’s Problem 强连通分量 最小路径覆盖
先找出强连通分量缩点,然后就是最小路径覆盖. 构造一个二分图,把每个点\(i\)拆成两个点\(X_i,Y_i\). 对于原图中的边\(u \to v\),在二分图添加一条边\(X_u \to Y_v\ ...
- [最小路径覆盖]拦截导弹
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
最新文章
- 你在打王者农药,有人却用iPhone来训练神经网络
- xx is not in the sudoers file 问题解决
- Stefan Tilkov:跳过单体应用,从微服务开始
- 分库分表就能无限扩容吗,解释得太好了
- 一个人会python能做什么_利用Python来预测一个人有没有女朋友!无所不能!
- ARM64的启动过程之(三):为打开MMU而进行的CPU初始化
- 一定要好好学习C语言
- android java 打开snd,使用SndPlaySound从内存中播放WAV
- 引commons-io工具类做文件的复制及导出
- java多线程写数据到数据库6_java多线程向数据库写入数据
- Java高并发编程实战7,ConcurrentHashMap详解
- Charles(1) 请求转发
- Hadoop原理和特性
- MATLAB图像处理学习日记之图像的自定义裁剪imcrop操作
- 过渡属性: transition
- JavaScript 动态表格操作
- 新兴媒体舆情传播动态实时监测的技术解决方案
- Bugku CTF Flask_FileUpload 解题思路
- PDF怎么设置密码保护不能打印?
- 华为鸿蒙源自那句话,你知道华为“鸿蒙”,却不知道出处吧?出自《山海经》?错...
热门文章
- mysql怎样在bat脚本中添加日志_如何在windows下用bat脚本定时备份mysql
- linux学习笔记(三):文件系统结构
- 选择排序 介绍与java实现
- 配置NAT超载(NAPT)
- 为什么程序员也能成为伟大的CEO
- 如何计算机械能的变化量,问:如何计算机械能变化量?
- signature=fc89d4352b6699754c14ce282ec75426,Broken chiral symmetry on a null plane
- ArcGIS GDB中要素类不可编辑
- 国内少有的Flutter干货分享:Flutter的原理及美团的实践!
- PPT 如何做好关卡设计