最小路径覆盖问题
来源:互联网 发布:黑马python基础班视频 编辑:程序博客网 时间:2024/03/28 16:12
问题描述
给定有向图 G=(V,E)。设 P 是 G 的一个简单路(顶点不相交)的集合。如果 V 中每个顶点恰好在 P 的一条路上,则称 P是 G 的一个路径覆盖。P 中路径可以从 V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。 设计一个有效算法求一个有向无环图G 的最小路径覆盖。 提示:设V={1,2,¼ ,n},构造网络 G1=(V1,E1)如下:
V
E
每条边的容量均为1。求网络G1 的(x0,y0)最大流。
编程任务
对于给定的给定有向无环图G,编程找出 G的一个最小路径覆盖。
数据输入
由文件input.txt提供输入数据。文件第1 行有 2个正整数 n和 m。n是给定有向无环图G 的顶点数, m是G 的边数。 接下来的 m行, 每行有 2 个正整数 i和 j, 表示一条有向边(i,j)。
结果输出
程序运行结束时,将最小路径覆盖输出到文件 output.txt 中。从第 1 行开始,每行输出
一条路径。文件的最后一行是最少路径数。
输入文件示例
input.txt 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
输出文件示例
output.txt 1 4 7 10 11 2 5 8 3 6 9 3
题解
变态的一道网络流题目,欺骗我感情
好吧,这是一道DAG最短路径覆盖问题。将原来的点进行拆点,对于原来的边(x,y),在网络流图中连接(
为了输出方案,我们可以定义一个数组next,对于每一个节点,我们在dfs的时候记录它的下一个节点,存储到next数组中,最终输出的时候用while循环即可。
到网上膜了一圈,感觉黄学长写得非常清楚,值得参考一下。
CODE:
#include<cstdio>#include<cstring>const int INF=1e9;struct queue{ int h,t; int a[500]; inline void clear(){h=1,t=0;} inline void push(int n){a[++t]=n;} inline int front(){return a[h];} inline void pop(){h++;} inline bool empty(){return h>t;}}q;struct edge{ int next,to,remain;}a[20000];int head[500];int deep[500];int next[500];int n,m,S,T,num=1,ans,x,y;inline int min(int a,int b){return a<b?a:b;}inline void add(int x,int y,int cap){ a[++num].next=head[x],a[num].to=y,a[num].remain=cap,head[x]=num; a[++num].next=head[y],a[num].to=x,head[y]=num;}inline bool bfs(){ memset(deep,0x3f,sizeof(deep)); q.clear(),q.push(S); deep[S]=0; while(!q.empty()) { int tmp=q.front();q.pop(); for(int i=head[tmp];i;i=a[i].next) if(deep[a[i].to]>INF&&a[i].remain) q.push(a[i].to),deep[a[i].to]=deep[tmp]+1; } return deep[T]<INF;}int dfs(int now,int limit){ if(now==T||!limit) return limit; int flow=0,f; for(int i=head[now];i;i=a[i].next) if(a[i].remain&&deep[a[i].to]==deep[now]+1&&(f=dfs(a[i].to,min(limit,a[i].remain)))) { next[now]=a[i].to; flow+=f,limit-=f,a[i].remain-=f,a[i^1].remain+=f; if(!limit) return flow; } deep[now]=-1; return flow;}inline int dinic(){ int ans=0; while(bfs()) ans+=dfs(S,INF); return ans;}void print(int now){ while(next[now]) { printf("%d ",now); now=next[now]-n; } printf("%d\n",now);}int main(){ scanf("%d%d",&n,&m); //1~n:顶点 n+1~2*n:拆点 2*n+1:源点 2*n+2:汇点 for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y+n,1); S=n<<1|1,T=S+1; for(int i=1;i<=n;i++) add(S,i,1); for(int i=1;i<=n;i++) add(n+i,T,1); ans=dinic(); for(int i=1;i<=n;i++) if(!next[n+i]) print(i); printf("%d",n-ans); return 0;}
0 0
- 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 若干最小路径覆盖问题
- swust1738: 最小路径覆盖问题
- poj1511 最小路径覆盖问题
- luogu2764 最小路径覆盖问题
- 最小路径覆盖问题 最小路径覆盖+输出解
- 最小路径覆盖问题(最小路径覆盖)
- 最小路径覆盖问题 (网络流解法)
- 网络流3最小路径覆盖问题
- [codevs 1904] 最小路径覆盖问题
- 【网络流】最小路径覆盖问题
- poj 2594(最小路径覆盖问题)
- 最小路径覆盖问题(二分图)
- Codevs 1904 最小路径覆盖问题
- 机器学习常见面试问题(一)
- 方法的创建、重载及递归调用
- Servlet 与 CGI 的比较
- JDK1.5新特性-枚举
- 四平方和(蓝桥杯入门)
- 最小路径覆盖问题
- 《Java高并发程序设计》学习 --2.2 初始线程:线程的基本操作
- iOS 中UIPasteboard
- jsp内置对象之session对象
- 《快学Scala》习题详解 第4章 映射和元组
- Java中对日期进行增加天数、月数、年
- Window环境下卸载Python3.6
- Linux—用户配置文件
- HttpClient连接管理