题目描述

«问题描述:

给定有向图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 最小路径覆盖问题(最大流)的更多相关文章

  1. [luoguP2764] 最小路径覆盖问题(最大流 || 二分图最大匹配)

    传送门 可惜洛谷上没有special judge,不然用匈牙利也可以过的,因为匈牙利在增广上有一个顺序问题,所以没有special judge就过不了了. 好在这个题的测试数据比较特殊,如果是网络流的 ...

  2. [题解] LuoguP2764 最小路径覆盖问题

    传送门 好久没做网络流方面的题发现自己啥都不会了qwq 题意:给一张有向图,让你用最少的简单路径覆盖所有的点. 考虑这样一个东西,刚开始,我们有\(n\)条路径,每条路径就是单一的一个点,那么我们的目 ...

  3. P2764 [网络流24题]最小路径覆盖问题[最大流]

    地址 这题有个转化,求最少的链覆盖→即求最少联通块. 设联通块个数$x$个,选的边数$y$,点数$n$个 那么有 $y=n-x$   即  $x=n-y$ 而n是不变的,目标就是在保证每个点入度.出度 ...

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

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

  5. BZOJ.1927.[SDOI2010]星际竞速(无源汇上下界费用流SPFA /最小路径覆盖)

    题目链接 上下界费用流: /* 每个点i恰好(最少+最多)经过一次->拆点(最多)+限制流量下界(i,i',[1,1],0)(最少) 然后无源汇可行流 不需要源汇. 注: SS只会连i',求SS ...

  6. Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)

    Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...

  7. 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】

    题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...

  8. BZOJ1927: [Sdoi2010]星际竞速(最小费用最大流 最小路径覆盖)

    题意 题目链接 Sol 看完题不难想到最小路径覆盖,但是带权的咋做啊?qwqqq 首先冷静思考一下:最小路径覆盖 = \(n - \text{二分图最大匹配数}\) 为什么呢?首先最坏情况下是用\(n ...

  9. LibreOJ 6002 最小路径覆盖(最大流)

    题解:最小路径覆盖=总点数减去最大匹配数,拆点,按照每条边前一个点连源点,后一个点连汇点跑最大流,即可跑出最大匹配数,然后减一减就可以了~ 代码如下: #include<queue> #i ...

随机推荐

  1. 逻辑学总结x

    逻辑学是研究事实联系: 肯定.否定: 条件 结论: 联系  规则: 的学问.

  2. BZOJ——T 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛

    http://www.lydsy.com/JudgeOnline/problem.php?id=1612 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1 ...

  3. WebKit载入流程 - 概述

    之前写了几篇载入流程的说明,是从下向上看,有点仅仅见树木不见森林的感觉.经过近期一段时间的学习,有了能加以概括抽象的方法. WebKit载入流程和页面组成是直接相关的,页面就是WebKit要载入的对象 ...

  4. Java中AtomicInteger的使用!!!

    今天在看Volley的源码的时候,看到里面使用了AtomicInteger这个类,曾经没用过,今天看了一下API学习了一下: 首先介绍一下这个类的用处,这个类主要是用来替换java中的自增和自减操作, ...

  5. url与图片

    http://restapi.amap.com/v3/staticmap?location=116.481485,39.990464&zoom=10&size=750*300& ...

  6. POJ2823 单调队列

    POJ2823 http://poj.org/problem?id=2823 最基础的单调队列,说是数据结构,其实就是一种更新数组数据的方法. 之前还准备用deque,超时了,直接head,tail快 ...

  7. 水 hdu5208 2015-04-20 21:03 36人阅读 评论(0) 收藏

    题意: 选择数列中两个数,使得最大公约数最大 分析: 类似筛选法,因为数值不大,可以用b[i]计算i是多少个数的因子.最后取最大的i即可. #include <bits/stdc++.h> ...

  8. 【实用篇】Android之应用程序实现自动更新功能

    我个人用的是友盟提供的自动更新组件,因此在这里只描述如何实用友盟提供的组件来完成程序的自动更新,步骤如下: 1.登录友盟官网,点击注册一个友盟账号. 2.注册成功后将会自动进入到添加新应用界面,选择添 ...

  9. Atcoder Grand Contest 107 A Biscuits

    A - Biscuits Time limit : 2sec / Memory limit : 256MB Score : 200 points Problem Statement There are ...

  10. VirtualBox内刚刚安装完Debian9系统,也无法设置共享文件夹。解决的方法就是安装VirtualBox客户端增强包。

    VirtualBox内刚刚安装完Debian9系统,也无法设置共享文件夹.解决的方法就是安装VirtualBox客户端增强包. 1.若直接安装客户端增强包会得到如下提示:root@debian:/op ...