LuoguP2764 最小路径覆盖问题(最大流)
题目描述
«问题描述:
给定有向图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 行开始,每行输出一条路径。文件的最后一行是最少路径数。
解题思路:
转换一下思路,需要覆盖,那么最多就需要点数条路径。
然后发现,有些路径可以合并,而且每合并一个点集,就少一条路径。
那么什么样的点可以合并呢,就是一条边相连的。
那么将一个点分裂成两个一个用于接受合并,一个用来提供合并。
相连的点,从起点的提供指向终点的接受,流量为$inf$
每个点都可以是起点终点所以向源汇点连$1$的边。
最大流最后拿n减掉就好了。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
const int oo=0x3f3f3f3f;
namespace stb{
template<class tnt>
class queue{
public:
queue(){h=,t=;}
int nxt(int x){if(x+==)return ;return x+;}
void push(tnt x){t=nxt(t);l[t]=x;return ;}
bool empty(void){return nxt(t)==h;}
tnt front(void){return l[h];}
void clear(void){h=,t=;}
void pop(void){h=nxt(h);}
private:
tnt l[];
int h,t;
};
};
struct pnt{
int hd;
int now;
int lyr;
int nxt;
bool nos;
}p[];
struct ent{
int twd;
int lst;
int vls;
}e[];
int cnt;
int n,m;
int s,t;
stb::queue<int>Q;
void ade(int f,int t,int v)
{
cnt++;
e[cnt].twd=t;
e[cnt].vls=v;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
bool Bfs(void)
{
Q.clear();
for(int i=;i<=n*+;i++)
p[i].lyr=;
p[s].lyr=;
Q.push(s);
while(!Q.empty())
{
int x=Q.front();
Q.pop();
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].lyr==&&e[i].vls>)
{
p[to].lyr=p[x].lyr+;
if(to==t)
return true;
Q.push(to);
}
}
}
return false;
}
int Dfs(int x,int fll)
{
if(x==t)
return fll;
for(int &i=p[x].now;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].lyr==p[x].lyr+&&e[i].vls>)
{
int ans=Dfs(to,std::min(fll,e[i].vls));
if(ans>)
{
e[i].vls-=ans;
e[((i-)^)+].vls+=ans;
p[x].nxt=to;
if(x!=s)
p[to-n].nos=true;
return ans;
}
}
}
return ;
}
void Dinic(void)
{
int ans=;
while(Bfs())
{
for(int i=;i<=*n+;i++)
p[i].now=p[i].hd;
int dlt;
while(dlt=Dfs(s,oo))
ans+=dlt;
}
for(int i=;i<=n;i++)
{
if(!p[i].nos)
{
for(int j=i;j!=t-n&&j>;j=p[j].nxt-n)
printf("%d ",j);
puts("");
}
}
printf("%d\n",n-ans);
return ;
}
int main()
{
scanf("%d%d",&n,&m);
s=n*+,t=n*+;
for(int i=;i<=n;i++)
{
ade(s,i,);
ade(i,s,);
ade(i+n,t,);
ade(t,n+i,);
}
for(int i=;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ade(a,b+n,oo);
ade(b+n,a,);
}
Dinic();
return ;
}
LuoguP2764 最小路径覆盖问题(最大流)的更多相关文章
- [luoguP2764] 最小路径覆盖问题(最大流 || 二分图最大匹配)
传送门 可惜洛谷上没有special judge,不然用匈牙利也可以过的,因为匈牙利在增广上有一个顺序问题,所以没有special judge就过不了了. 好在这个题的测试数据比较特殊,如果是网络流的 ...
- [题解] LuoguP2764 最小路径覆盖问题
传送门 好久没做网络流方面的题发现自己啥都不会了qwq 题意:给一张有向图,让你用最少的简单路径覆盖所有的点. 考虑这样一个东西,刚开始,我们有\(n\)条路径,每条路径就是单一的一个点,那么我们的目 ...
- P2764 [网络流24题]最小路径覆盖问题[最大流]
地址 这题有个转化,求最少的链覆盖→即求最少联通块. 设联通块个数$x$个,选的边数$y$,点数$n$个 那么有 $y=n-x$ 即 $x=n-y$ 而n是不变的,目标就是在保证每个点入度.出度 ...
- 【wikioi】1904 最小路径覆盖问题(最大流+坑人的题+最小路径覆盖)
http://wikioi.com/problem/1904/ 这题没看数据的话是一个大坑(我已报告官方修复了),答案只要求数量,不用打印路径...orz 最小路径覆盖=n-最大匹配,这个我在说二分图 ...
- BZOJ.1927.[SDOI2010]星际竞速(无源汇上下界费用流SPFA /最小路径覆盖)
题目链接 上下界费用流: /* 每个点i恰好(最少+最多)经过一次->拆点(最多)+限制流量下界(i,i',[1,1],0)(最少) 然后无源汇可行流 不需要源汇. 注: SS只会连i',求SS ...
- Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)
Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...
- 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】
题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...
- BZOJ1927: [Sdoi2010]星际竞速(最小费用最大流 最小路径覆盖)
题意 题目链接 Sol 看完题不难想到最小路径覆盖,但是带权的咋做啊?qwqqq 首先冷静思考一下:最小路径覆盖 = \(n - \text{二分图最大匹配数}\) 为什么呢?首先最坏情况下是用\(n ...
- LibreOJ 6002 最小路径覆盖(最大流)
题解:最小路径覆盖=总点数减去最大匹配数,拆点,按照每条边前一个点连源点,后一个点连汇点跑最大流,即可跑出最大匹配数,然后减一减就可以了~ 代码如下: #include<queue> #i ...
随机推荐
- 鼠标点击textarea后,在光标后追加内容
$("#insertMsg").on("click",function(){ //获取下拉选项框的值 var textFeildValue = $(" ...
- [JLOI2011]飞行路线(分层图)
[JLOI2011]飞行路线 题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在 n 个城市设有业务,设这些城市分别标记为 0 到 n−1 ,一共有 m ...
- 洛谷 P1407 工资
P1407 工资 题目描述 有一家世界级大企业,他们经过调查,发现了一个奇特的现象,竟然在自己的公司里,有超过一半的雇员,他们的工资完全相同! 公布了这项调查结果后,众多老板对于这一现象很感兴趣,他们 ...
- 手动创建DataTable并添加数据
DataTable dt=new DataTable(); DataColumn dc=dt.Columns.Add("OBJECTID",Type.GetType("S ...
- volatile的含义
从词面上来讲.volatile的意思是易变的,也就是说.在程序执行的过程中,有一些变量可能会被莫名其妙的改变,而优化器为了节约时间.有时候不会重读这个变量的真实值,而是去读在寄存器的备份,这种话,这个 ...
- 使用Hadoop ACL 控制訪问权限
使用Hadoop ACL 控制訪问权限 一.HDFS訪问控制 hdfs-site.xml设置启动acl <property> <name>dfs.permissions.en ...
- 学习 shell —— 创建序列数组
list/array 1. seq 方法创建 基本用法: $ a_num_seq = ($seq 5) $ echo $a_num_seq 1 2 3 4 5 a_num_seq 得到是字符串,不同之 ...
- 关于Javascript的forEach 和 map
本篇博客转载自 https://blog.fundebug.com/2018/02/05/map_vs_foreach/ 如果你已经有使用JavaScript的经验,你可能已经知道这两个看似相同的方法 ...
- POJ 3622 multiset
思路: 放一个链接 是我太懒了 http://blog.csdn.net/mars_ch/article/details/52835978 嗯她教的我(姑且算是吧) (一通乱搞就出来了-) //By ...
- 编写jsp代码时出现的红色提示线错误
将jsp页面关闭:点击"X"号,例如图中的index.jsp页面的”X"号,或者右键—“close"也可以. 双击jsp页面:重新启动页面,页面的错误提示线 ...