题目描述

«问题描述:

给定有向图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

说明

1<=n<=150,1<=m<=6000

思路:

  网络流24题之一;

  还是那条性质,求最小割;

  每条有向边的u,v加边都是u,v+n;

  求出最大流,ans=n-最大流;

  然后,我们在求最大流的时候把匹配的点和边做标记以输出路径;

来,上代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define INF 0x7ffffff using namespace std; struct EdgeType {
int to,next,flow;
};
struct EdgeType edge[]; int if_z,n,m,cnt=,head[],s=,t=;
int deep[],next[],ans; bool if_[]; char Cget; inline void in(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void edge_add(int u,int v,int w)
{
edge[++cnt].to=v,edge[cnt].flow=w,edge[cnt].next=head[u],head[u]=cnt;
edge[++cnt].to=u,edge[cnt].flow=,edge[cnt].next=head[v],head[v]=cnt;
} bool BFS()
{
queue<int>que;
memset(deep,-,sizeof(deep));
que.push(s),deep[s]=;
while(!que.empty())
{
int pos=que.front();
for(int i=head[pos];i;i=edge[i].next)
{
if(deep[edge[i].to]<&&edge[i].flow>)
{
deep[edge[i].to]=deep[pos]+;
if(edge[i].to==t) return true;
que.push(edge[i].to);
}
}
que.pop();
}
return false;
} int flowing(int now,int flow)
{
if(now==t||flow==) return flow;
int oldflow=;
for(int i=head[now];i;i=edge[i].next)
{
if(deep[edge[i].to]!=deep[now]+||edge[i].flow==) continue;
int pos=flowing(edge[i].to,min(flow,edge[i].flow));
if(pos>)
{
next[now]=edge[i].to;
if(edge[i].to>n) if_[edge[i].to-n]=true;
}
flow-=pos;
oldflow+=pos;
edge[i].flow-=pos;
edge[i^].flow+=pos;
if(flow==) return oldflow;
}
return oldflow;
} void dinic()
{
while(BFS()) ans-=flowing(s,INF);
} int main()
{
in(n),in(m);int u,v;ans=n;
for(int i=;i<=m;i++)
{
in(u),in(v);
edge_add(u,v+n,INF);
}
for(int i=;i<=n;i++)
{
edge_add(s,i,);
edge_add(i+n,t,);
}
dinic();
for(int i=;i<=n;i++)
{
if(if_[i]) continue;
int pos=i;
printf("%d",pos);
while(next[pos])
{
if(next[pos]>n) next[pos]-=n;
printf(" %d",next[pos]);
pos=next[pos];
}
printf("\n");
}
printf("%d\n",ans);
return ;
}

AC日记——最小路径覆盖问题 洛谷 P2764的更多相关文章

  1. AC日记——无线网络发射器选址 洛谷 P2038

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

  2. AC日记——校门外的树 洛谷 P1047

    题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种 ...

  3. AC日记——小A的糖果 洛谷七月月赛

    小A的糖果 思路: for循环贪心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #defi ...

  4. AC日记——矩阵取数游戏 洛谷 P1005

    矩阵取数游戏 思路: dp+高精: 代码: #include <bits/stdc++.h> using namespace std; #define ll long long struc ...

  5. AC日记——红色的幻想乡 洛谷 P3801

    红色的幻想乡 思路: 线段树+容斥原理: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #de ...

  6. AC日记——妖梦拼木棒 洛谷 P3799

    妖梦拼木棒 思路: 神特么题: 代码: #include <bits/stdc++.h> using namespace std; #define mod 1000000007LL int ...

  7. AC日记——妖梦斩木棒 洛谷 P3797

    妖梦斩木棒 思路: 略坑爹: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define m ...

  8. AC日记——[SDOI2009]HH去散步 洛谷 P2151

    [SDOI2009]HH去散步 思路: 矩阵快速幂递推(类似弗洛伊德): 给大佬跪烂-- 代码: #include <bits/stdc++.h> using namespace std; ...

  9. AC日记——聪明的质监员 洛谷 P1314

    聪明的质监员 思路: 二分: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define l ...

随机推荐

  1. 如何用 CSS 和 D3 创作旋臂粒子动画

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/xJrOqd 可交互视频 ...

  2. vue 使用lib-flexable,px2rem 进行移动端适配 但是引入的第三方UI组件 vux 的样式缩小,解决方案

    最近在写移动端项目,就想用lib-flexable,px2rem来进行适配,把px转换成rem但是也用到了第三方UI组件库vux,把这个引入发现一个问题就是vux的组件都缩小了,在网上找不到答案,最后 ...

  3. 小试nginx日志分析xlog

    nginx配置: http { #...其他配置 log_format tpynormal '$remote_addr | [$time_local] | $host | "$request ...

  4. 在linux下安装并运行scrapyd

    系统:centos7.4 安装scrapyd:pip isntall scrapyd 因为我腾讯云上是python2与python3并存的 所以我执行的命令是:pip3 isntall scrapyd ...

  5. type和object

    一.定义 1.object是所有新式类的父类 2.type是所有类的类    二.解析   下面通过代码来比较一下object和type的关系(__class__获取所属的类,__bases__获取父 ...

  6. 网络流之Dinic算法

    初学网络流.存一下Dinic板子. 复杂度O(n^2*m) UVA - 1515 Pool construction 把每个草地与 S 相连,花费为dig,每个洞与 T 相连,花费为 然后对于每个两个 ...

  7. 实践自己的WebSite______流水

    尝试从头至尾搭建一个MVC的网站,主要以流水的方式进行进度和记录,而不讨论技术的部分. 1,在Controller下创建两个文件夹,分别为sys和Business,分别对应于系统功能和业务逻辑.比如登 ...

  8. electron 安装

    1.从网上下载的是nodejs的v0.10.42版本的安装文件,安装node-v0.10.42-x86.msi都使用默认安装,安装完成后会安装在C:\Program Files\nodejs\目录下, ...

  9. 取出列表中第N大的数

    array=list(range(10)) random.shuffle(array) print(array) def func1(array,n): d,k={},n while k>0: ...

  10. MySQL数据库详解(二)执行SQL更新时,其底层经历了哪些操作?

    ​ 前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更 ...