[FZYZOJ 1356] 8-3 最小路径覆盖问题

P1356 -- 8-3 最小路径覆盖问题

时间限制:1000MS

内存限制:131072KB

Description

给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。设计一个有效算法求一个有向无环图G 的最小路径覆盖。

Input Format

第1 行有2个正整数n和m。n是给定有向无环图G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。

Output Format

从第1 行开始,每行输出一条路径(行末无空格,有空格你就wa了)。文件的最后一行是最少路径数。

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

Hint

n<=150 m<=6000

【题解】

最小路径覆盖可以用二分图匹配/网络流来做。

具体的就是若从A到B有路径,连A,B+n即可。

然后匈牙利搞一搞就好了。

 1 #include <stdio.h>
 2 #include <string.h>
 3 using namespace std;
 4
 5 const int V=500,E=70010;
 6 int n,m;
 7 bool vis[V];
 8 int fa[V],head[V],to[E],next[E],ans=0;
 9
10 bool hungry(int u) {
11     for (int i=head[u];i;i=next[i]) {
12         if(!vis[to[i]]) {
13             vis[to[i]]=1;
14             if(!fa[to[i]]||hungry(fa[to[i]])) {
15                 fa[to[i]]=u;
16                 fa[u]=to[i];
17                 return 1;
18             }
19         }
20     }
21     return 0;
22 }
23
24 inline int g() {
25     int x=0,f=1;char ch=getchar();
26     while(ch<‘0‘||ch>‘9‘) {
27         if(ch==‘-‘) f=-1;
28         ch=getchar();
29     }
30     while(ch>=‘0‘&&ch<=‘9‘) {
31         x=(x<<1)+(x<<3)+ch-‘0‘;
32         ch=getchar();
33     }
34     return x*f;
35 }
36
37 int main() {
38     n=g(),m=g();
39     for (int i=1,a,b;i<=m;++i) {
40         a=g(),b=g();
41         to[i]=b+n;
42         next[i]=head[a];
43         head[a]=i;
44     }
45     for (int i=1;i<=n;++i) {
46         if(fa[i]) continue;
47         memset(vis,0,sizeof(vis));
48         if(hungry(i)) ++ans;
49     }
50     memset(vis,0,sizeof(vis));
51     for (int i=1;i<=n;++i) {
52         if(!vis[i]) {
53             vis[i]=1;
54             printf("%d",i);
55             for (int j=fa[i];j;j=fa[j-n]) {
56                 printf(" %d",j-n);
57                 vis[j-n]=1;
58             }
59             printf("\n");
60         }
61     }
62     printf("%d\n",n-ans);
63     return 0;
64 }

时间: 2024-10-14 19:51:48

[FZYZOJ 1356] 8-3 最小路径覆盖问题的相关文章

hiho 第118周 网络流四&#183;最小路径覆盖

描述 国庆期间正是旅游和游玩的高峰期. 小Hi和小Ho的学习小组为了研究课题,决定趁此机会派出若干个调查团去沿途查看一下H市内各个景点的游客情况. H市一共有N个旅游景点(编号1..N),由M条单向游览路线连接.在一个景点游览完后,可以顺着游览线路前往下一个景点. 为了避免游客重复游览同一个景点,游览线路保证是没有环路的. 每一个调查团可以从任意一个景点出发,沿着计划好的游览线路依次调查,到达终点后再返回.每个景点只会有一个调查团经过,不会重复调查. 举个例子: 上图中一共派出了3个调查团: 1

hdu3861 强连通+最小路径覆盖

题意:有 n 个点,m 条边的有向图,需要将这些点分成多个块,要求:如果两点之间有路径能够互相到达,那么这两个点必须分在同一块:在同一块内的任意两点相互之间至少要有一条路径到达,即 u 到达 v 或 v 到达 u:每个点都只能存在于单独一个块内.问最少需要划分多少块. 首先,对于如果两点之间能够相互到达则必须在同一块,其实也就是在同一个强连通分量中的点必须在同一块中,所以首先就是强连通缩点.然后在同一块内的任意两点之间要有一条路,那么其实就是对于一块内的强连通分量,至少要有一条路径贯穿所有分量.

COGS728. [网络流24题] 最小路径覆盖问题

算法实现题8-3 最小路径覆盖问题(习题8-13) ´问题描述: 给定有向图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)最大流.

【最小路径覆盖】BZOJ2150-部落战争

[题目大意] 给出一张图,'*'表示不能走的障碍.已知每只军队可以按照r*c的方向行军,且军队与军队之间路径不能交叉.问占据全部'.'最少要多少支军队? [思路] 首先注意题意中有说“军队只能往下走”,弄清楚方向. 从某点往它能走的四个点走一趟,连边.最小路径覆盖=总数-二分图最大匹配. 哦耶!老了,连匈牙利的板子都敲错orzzzzzz 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=55; 4 int m,n

有向无环图(DAG)的最小路径覆盖

DAG的最小路径覆盖 定义:在一个有向图中,找出最少的路径,使得这些路径经过了所有的点. 最小路径覆盖分为最小不相交路径覆盖和最小可相交路径覆盖. 最小不相交路径覆盖:每一条路径经过的顶点各不相同.如图,其最小路径覆盖数为3.即1->3>4,2,5. 最小可相交路径覆盖:每一条路径经过的顶点可以相同.如果其最小路径覆盖数为2.即1->3->4,2->3>5. 特别的,每个点自己也可以称为是路径覆盖,只不过路径的长度是0. DAG的最小不相交路径覆盖 算法:把原图的每个点

hdu 3861 The King’s Problem (强连通+最小路径覆盖)

The King's Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1637    Accepted Submission(s): 600 Problem Description In the Kingdom of Silence, the king has a new problem. There are N cit

POJ 3020 Antenna Placement ,二分图的最小路径覆盖

题目大意: 一个矩形中,有N个城市'*',现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市. 问至少放置多少个基站才能使得所有的城市都覆盖无线? 无向二分图的最小路径覆盖 = 顶点数 –  最大二分匹配数/2 路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联: #include<cstdio> #include<cstring> #include<vector> #include<algor

Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)

题意:给出一张完全图,所有的边的边权都是 y,现在给出图的一个生成树,将生成树上的边的边权改为 x,求一条距离最短的哈密顿路径. 先考虑x>=y的情况,那么应该尽量不走生成树上的边,如果生成树上有一个点的度数是n-1,那么必然需要走一条生成树上的边,此时答案为x+y*(n-2). 否则可以不走生成树上的边,则答案为y*(n-1). 再考虑x<y的情况,那么应该尽量走生成树上的边,由于树上没有环,于是我们每一次需要走树的一条路,然后需要从非生成树上的边跳到树的另一个点上去, 显然跳的越少越好,于

POWOJ 1739: 魔术球问题 DAG最小路径覆盖转最大流

1739: 魔术球问题 题意: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.对于给定的n,计算在n根柱子上最多能放多少个球. tags: 对大佬来说应该是很素的一道题,但某还是花了好多时间才做出来.. 一开始连建图都有点懵,然后最小路径还是新概念,最大匹配也不太懂,最大流倒是会一点. 然后要打印答案,也不