洛谷2764 最小路径覆盖问题

问题描述:

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

编程任务:

对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。

Input Format

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

Output Format

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

网络流经典题,网络流24题之一

题意就是在一个有向无环图里,用最少的路径数覆盖每一个点。

就是如果i,j有一条边,就将i和j+n连一条边,跑一下最大匹配

最少路径条数ans=n-最大匹配数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10005
#define inf 0x7fffff
int n,m;
int ans;
int cnt=1;
int to[maxn],head[maxn],q[maxn],h[maxn];
bool mark[maxn];
struct edge{
    int next,to,w;
}e[2000005];
void ins(int u,int v,int w){
    cnt++;
    e[cnt].next=head[u];e[cnt].to=v;e[cnt].w=w;
    head[u]=cnt;
}
void insert(int u,int v,int w){
    ins(u,v,w);ins(v,u,0);
}
bool bfs(){
    int t=0,w=1;
    int now;
    memset(h,-1,sizeof h);
    q[0]=h[0]=0;
    while(t<w){
        now=q[t];t++;
        for(int i=head[now];i;i=e[i].next){
            int s=e[i].to;
            if(e[i].w&&h[s]==-1){
                h[s]=h[now]+1;
                q[w++]=s;
            }
        }
    }
    if(h[8001]==-1)return 0;
    return 1;
}
int dfs(int x,int f){
    if(x==8001)return f;
    int w,used=0;
    for(int i=head[x];i;i=e[i].next){
        int s=e[i].to;
        if(e[i].w&&h[s]==h[x]+1){
            w=f-used;
            w=dfs(s,min(w,e[i].w));
            if(w){
                to[x]=s;
                if(s-n>0)mark[s-n]=1;
            }
            e[i].w-=w;
            e[i^1].w+=w;
            used+=w;
            if(used==f)return f;
        }
    }
    if(!used)h[x]=-1;
    return used;
}
void dinic(){
    while(bfs())ans-=dfs(0,inf);
}
int main(){
    scanf("%d%d",&n,&m);
    int x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        insert(x,n+y,inf);
    }
    for(int i=1;i<=n;i++)insert(0,i,1);
    for(int i=1;i<=n;i++)insert(i+n,8001,1);
    ans=n;
    dinic();
    for(int i=1;i<=n;i++){
        if(mark[i])continue;
        int k=i;
        printf("%d ",i);
        while(to[k]){
            printf("%d ",to[k]-n);
            k=to[k]-n;
        }
        printf("\n");
    }
    printf("%d",ans);
}

原文地址:https://www.cnblogs.com/Elfish/p/8277464.html

时间: 2024-10-07 12:55:41

洛谷2764 最小路径覆盖问题的相关文章

洛谷 P2764 最小路径覆盖问题【匈牙利算法】

经典二分图匹配问题.把每个点拆成两个,对于原图中的每一条边(i,j)连接(i,j+n),最小路径覆盖就是点数n-二分图最大匹配.方案直接顺着匹配dsf.. #include<iostream> #include<cstdio> using namespace std; const int N=505,M=120005; int n,m,h[N],cnt,lk[N],t,v[N],ans; struct qwe { int ne,to; }e[M]; int read() { int

luogu 2764 最小路径覆盖问题 | 最大匹配

luogu 2764 最小路径覆盖 = n - 最大匹配 1 #include <cstdio> 2 #include <string> 3 #include <vector> 4 #include <queue> 5 #include <cstring> 6 7 const int N = 200, INF = 0x3f3f3f3f; 8 9 int read() { 10 int x = 0, f = 1; 11 char c = getch

洛谷 P2764 LibreOJ 6002 最小路径覆盖问题

题目描述 «问题描述: 给定有向图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 )最大流. «编程任务:

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