Description

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

Input

由文件input.txt提供输入数据。文件第1 行有2个正整数n和m。n是给定有向无环图 G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。

Output

程序运行结束时,将最小路径覆盖输出到文件output.txt 中。从第1 行开始,每行输出 一条路径。文件的最后一行是最少路径数。
Sample Input
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
Sample Output
1 4 7 10 11 2 5 8 3 6 9 3
 
题解:
每一个点拆成i和i+n两个,每一个表示他在边中是前驱还是后继,然后所有的前驱init(S,i,1)所有的后继(i+n,T,1)
每一条边(u,v)改成u的前驱到v的后继有一条(u,v+n,INF)的边
然后答案为n-最大流
然后输出路径,已知路径的开始一定后继没有被访问过,所以i+n到T的边依旧为1,可以找出所有路径的开始节点。
然后就是判断他和哪些边匹配过,不断递归输出.
细节很巧妙,详情看代码:
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=,M=,INF=;
int gi(){
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>='' && ch<='')str=str*+ch-'',ch=getchar();
return str;
}
int n,m,num=,head[N],S=,T,d[N];
struct Lin{
int next,to,dis;
}a[M];
void init(int x,int y,int z){
a[++num].next=head[x];
a[num].to=y;
a[num].dis=z;
head[x]=num;
a[++num].next=head[y];
a[num].to=x;
a[num].dis=;
head[y]=num;
}
int q[N],dep[N];
bool bfs()
{
memset(dep,,sizeof(dep));
q[]=S;dep[S]=;
int x,u,t=,sum=;
while(t!=sum)
{
x=q[++t];
for(int i=head[x];i;i=a[i].next){
u=a[i].to;
if(dep[u] || a[i].dis<=)continue;
dep[u]=dep[x]+;q[++sum]=u;
}
}
return dep[T];
}
int dfs(int x,int flow)
{
if(T==x || !flow)return flow;
int u,tmp,tot=;
for(int i=head[x];i;i=a[i].next){
u=a[i].to;
if(dep[u]!=dep[x]+ || a[i].dis<=)continue;
tmp=dfs(u,min(a[i].dis,flow));
tot+=tmp;flow-=tmp;
a[i].dis-=tmp;a[i^].dis+=tmp;
if(!flow)break;
}
return tot;
}
int maxflow()
{
int tmp,tot=;
while(bfs()){
tmp=dfs(S,INF);
while(tmp)tot+=tmp,tmp=dfs(S,INF);
}
return tot;
}
void hfs(){
int u;
for(int i=head[T];i;i=a[i].next){
if(!a[i].dis)d[a[i].to]=true;
}
}
void Print(int x)
{
printf("%d ",x);
for(int i=head[x];i;i=a[i].next){
if(a[i].to!=S && a[i].dis==INF-)Print(a[i].to-n);
}
}
int main()
{
int x,y;
n=gi();m=gi();
T=*n+;
for(int i=;i<=n;i++)init(S,i,),init(i+n,T,);
for(int i=;i<=m;i++){
x=gi();y=gi();
init(x,y+n,INF);
}
int tp=maxflow();
hfs();
for(int i=;i<=n;i++){
if(!d[i+n])continue;
Print(i);
printf("\n");
}
printf("%d",n-tp);
}

【PowerOJ1738】最小路径覆盖的更多相关文章

  1. 【PowerOJ1738&网络流24题】最小路径覆盖问题 (最大流)

    题意: 思路: [问题分析] 有向无环图最小路径覆盖,可以转化成二分图最大匹配问题,从而用最大流解决. [建模方法] 构造二分图,把原图每个顶点i拆分成二分图X,Y集合中的两个顶点Xi和Yi.对于原图 ...

  2. 【HDU1960】Taxi Cab Scheme(最小路径覆盖)

    Taxi Cab Scheme Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. loj 1429(可相交的最小路径覆盖)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1429 思路:这道题还是比较麻烦的,对于求有向图的可相交的最小路径覆盖,首先要解决成环问 ...

  4. 【HDU3861 强连通分量缩点+二分图最小路径覆盖】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...

  5. POJ 3216 最小路径覆盖+floyd

    Repairing Company Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 6646   Accepted: 178 ...

  6. POJ3020Antenna Placement(最小路径覆盖+重在构图)

    Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7788   Accepted: 3880 ...

  7. POJ 3020 (二分图+最小路径覆盖)

    题目链接:http://poj.org/problem?id=3020 题目大意:读入一张地图.其中地图中圈圈代表可以布置卫星的空地.*号代表要覆盖的建筑物.一个卫星的覆盖范围是其周围上下左右四个点. ...

  8. 【wikioi】1904 最小路径覆盖问题(最大流+坑人的题+最小路径覆盖)

    http://wikioi.com/problem/1904/ 这题没看数据的话是一个大坑(我已报告官方修复了),答案只要求数量,不用打印路径...orz 最小路径覆盖=n-最大匹配,这个我在说二分图 ...

  9. hiho 第118周 网络流四·最小路径覆盖

    描述 国庆期间正是旅游和游玩的高峰期. 小Hi和小Ho的学习小组为了研究课题,决定趁此机会派出若干个调查团去沿途查看一下H市内各个景点的游客情况. H市一共有N个旅游景点(编号1..N),由M条单向游 ...

随机推荐

  1. 201621123060《JAVA程序设计》第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车. 2.1 简述如何 ...

  2. 《Language Implementation Patterns》之 符号表

    前面的章节我们学会了如何解析语言.构建AST,如何访问重写AST,有了这些基础,我们可以开始进行"语义分析"了. 在分析语义的一个基本方面是要追踪"符号",符号 ...

  3. bzoj千题计划245:bzoj1095: [ZJOI2007]Hide 捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095 查询最远点对,带修改 显然可以用动态点分治 对于每个点,维护两个堆 堆q1[x] 维护 点分树 ...

  4. SENet

     \(\bf F_{tr}\) 为标准卷积操作 \(\bf F_{sq}\) 为 Global Average Pooling \(\bf F_{ex}\) 为两层全连接网络(可以看做两个1×1卷积 ...

  5. PHP环境手动搭建wamp-----Apache+MySQL+PHP

    首先下载分别下载Apache+MySQL+PHP. 然后分别解压到文件夹中. 1.安装Apache 1)检查80端口是否占用 说明:apache软件占用80软件,在计算机中一个端口只能被一个软件占用 ...

  6. Oracle闪回技术

    (一)闪回技术概要 闪回技术是数据库备份与恢复的重要补充手段,主要包括以下7种特性: 特性 原理 数据库支持 闪回查询(Flashback Query) 利用undo表空间中的回退信息,查询过去某个时 ...

  7. angular2 学习笔记 ( Dynamic Component 动态组件)

    更新 2018-02-07 详细讲一下 TemplateRef 和 ViewContainerRef 的插入 refer : https://segmentfault.com/a/1190000008 ...

  8. Linux进程管理:查杀进程

    一.查看进程 Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢? 两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格,System V风格 ...

  9. GIT入门笔记(17)- 创建分支dev_lsq, 提交到代码

    git服务器上默认的已经有主干和test分支. 开发人员提交代码流程如下: 1.用switch to->new branch创建dev1分支 2.push branch提交到dev1分支 3.在 ...

  10. Docker的容器操作

    启动一次性运行的容器 入门级例子:从ubuntu:14.04镜像启动一个容器,成功后在容器内部执行/bin/echo 'hello world'命令,如果当前物理机没有该镜像,则执行docker pu ...