zoukankan      html  css  js  c++  java
  • 【网络流24题】最小路径覆盖问题

    【网络流24题】最小路径覆盖问题

    Description

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

    Input

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

    Output

    第1行开始,每行输出一条(字典序)路径。最后一行是最少路径数。

    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

    数据范围: 
    1<=n<=150,1<=m<=6000 
    提示: 
    设V={1,2,... ,n},构造网络G1=(V1,E1)如下: 
    P 
    每条边的容量均为1。求网络G1的(x0,y0)最大流。

    一道巨坑题。。。这是链接【只有COGS支持SPJ,我也是呵呵了】

    思路:既然每个点只能经过一次,不妨把一个点拆成A、B两点,对原图中a->b的边,连接a.A->b.B,跑一遍匈♂牙利,酱紫之后就可以发现点数-匹配数==剩下点数(废话),一条路径可以解决一堆剩下的点,于是ans=n-匹配数

     1 // It is made by XZZ
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define File
     6 #define Fname "path3"
     7 using namespace std;
     8 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
     9 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    10 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    11 #define il inline
    12 #define rg register
    13 #define vd void
    14 #define t (dis[i])
    15 typedef long long ll;
    16 il int gi(){
    17     rg int x=0;rg char ch=getchar();
    18     while(ch<'0'||ch>'9')ch=getchar();
    19     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    20     return x;
    21 }
    22 const int maxn=151<<1,maxm=6002;
    23 int id=0,fir[maxn],dis[maxm],nxt[maxm];
    24 il vd add(int a,int b){
    25     nxt[++id]=fir[a],fir[a]=id,dis[id]=b;
    26 }
    27 inline bool BFS() {
    28     int bfs[maxn];
    29     memset(dep,0,sizeof dep);
    30     bfs.push(S);
    31     bool yes[600]= {0};
    32     yes[S]=1,dep[S]=0;
    33     while(!bfs.empty()) {
    34     int now=bfs.front();
    35     for(int i=fir[now]; i; i=nxt[i])
    36         if(w[i]>0&&!yes[t])
    37         yes[t]=1,bfs.push(t),dep[t]=dep[now]+1;
    38     bfs.pop();
    39     }
    40     return yes[T];
    41 }
    42 int dep[maxn];
    43 inline int Dinic(int now,int h) {
    44     if(now==T)return h;
    45     int ans=0;
    46     for(int i=fir[now]; i; i=nxt[i])
    47     if(w[i]>0&&dep[t]==dep[now]+1) {
    48         int D=Dinic(t,min(h,w[i]));
    49         w[i]-=D,w[i^1]+=D,ans+=D,h-=D;
    50         if(h==0)return ans;
    51     }
    52     return ans;
    53 }
    54 int main(){
    55     freopen(Fname".in","r",stdin);
    56     freopen(Fname".out","w",stdout);
    57     rg int n=gi(),m=gi();
    58     while(m--){rg int i=gi(),j=gi();add(i,j+n);}
    59     memset(match,-1,sizeof match);
    60     int ans=0;
    61     drep(i,n,1){
    62     memset(vis,0,sizeof vis);
    63     vis[i]=1;if(dfs(i))++ans;
    64     }
    65     drep(i,n+n,n+1)if(match[i]+1)to[match[i]]=i-n,in[i-n]=1;
    66     rep(i,1,n)if(!in[i]){
    67     int now=i;printf("%d ",now);
    68     while(to[now])now=to[now],printf("%d ",now);
    69     puts("");
    70     }
    71     printf("%d
    ",n-ans);
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    NFC技术:让Android自动打开网页
    NFC技术:让Android自动运行程序
    NFC技术:概述
    路由器端口映射实现外网访问本地服务器
    Java之MySql数据库链接
    最短路径之Dijkstra算法及实例分析
    各种排序算法的时间性能比较
    C#实现基于ffmpeg加虹软的人脸识别
    虹软SDK在nodejs中的集成
    Android 虹软2.0人脸识别,注册失败问题 分析synchronized的作用
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7210698.html
Copyright © 2011-2022 走看看