AC日记——最小路径覆盖问题 洛谷 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
思路:
网络流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的更多相关文章
- AC日记——无线网络发射器选址 洛谷 P2038
题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...
- AC日记——校门外的树 洛谷 P1047
题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种 ...
- AC日记——小A的糖果 洛谷七月月赛
小A的糖果 思路: for循环贪心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #defi ...
- AC日记——矩阵取数游戏 洛谷 P1005
矩阵取数游戏 思路: dp+高精: 代码: #include <bits/stdc++.h> using namespace std; #define ll long long struc ...
- AC日记——红色的幻想乡 洛谷 P3801
红色的幻想乡 思路: 线段树+容斥原理: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #de ...
- AC日记——妖梦拼木棒 洛谷 P3799
妖梦拼木棒 思路: 神特么题: 代码: #include <bits/stdc++.h> using namespace std; #define mod 1000000007LL int ...
- AC日记——妖梦斩木棒 洛谷 P3797
妖梦斩木棒 思路: 略坑爹: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define m ...
- AC日记——[SDOI2009]HH去散步 洛谷 P2151
[SDOI2009]HH去散步 思路: 矩阵快速幂递推(类似弗洛伊德): 给大佬跪烂-- 代码: #include <bits/stdc++.h> using namespace std; ...
- AC日记——聪明的质监员 洛谷 P1314
聪明的质监员 思路: 二分: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define l ...
随机推荐
- destoon后台权限-不给客户创始人权限并屏蔽部分功能
1.根目录下后台入口文件admin.php $_founder = $CFG['founderid'] == $_userid ? $_userid : 0; // $CFG['founderid ...
- jsp内置对象及其方法
JSP中一共预先定义了9个这样的对象,分别为: request. response. session. application. out. pagecontext. con ...
- linux中vim永久显示行号、开启语法高亮
vim ~/.vimrc 进入insert模式,在最后加二行 syntax on set nu! 保存收工. 设置用视图模式的缩进为4个空格 set smartindent set tabstop=4 ...
- STM32CUBEMX入门学习笔记1:软件的简单介绍
STM32CUBEMX是ST公司设计的一款免费软件,软件可以通过其官网下载.现在已经下载到.通过STM32CUBEMX可以完成从单片机选型,程序初始化,中断配置……工作.并生成对应的"HAL ...
- STVP烧录教程
可以运行独立的烧录软件ST Visual Programmer (STVP)进行STM8芯片烧录.运行“开始”->ST Toolset->Development Tools -> S ...
- Freemaker模板指令
${...}:Freemaker将会输出真实的值来替换大括号内的表达式.这样的表达式被称为interpolation(插值). FTL标签(Freemaker模板的语言标签):FTL标签和HTML标签 ...
- 蓝桥杯Java输入输出相关
转载自:http://blog.csdn.net/Chen_Tongsheng/article/details/53354169 一.注意点 1. 类名称必须采用public class Main方式 ...
- C++ 指针的小知识
看个小例子: char* fun1(){ char * p = (char*)malloc(100); p = "helloww"; return p;} void fun2(ch ...
- 在线安装ipa,超链接下载ipa
在线安装ipa包其实是OTA实现,先粘一下OTA解释 OTA OTA即Over-the-Air,简单来说就是通过无线的方式发送指令给设备,具体针对iOS的设备,比如iphone .ipad等,让开发者 ...
- LiveScript 流程控制、循环以及列表推导式
The LiveScript Book The LiveScript Book Generators and Yield 你可以在你的 LiveScript 代码中使用 Ecmascript ...