zoukankan      html  css  js  c++  java
  • [Cogs728] [网络流24题#3] 最小路径覆盖 [网络流,最大流,二分图匹配]

    建图:源点—>边的起点(集合1中的)—>边的终点(集合2中的)—>汇点,所有边权均为1,

    计算最大流,最后枚举起点的出边,边权为0的即为匹配上的,

    可以这样理解:每条边表示起点和终点形成一组可选匹配,所以每个点只能被匹配1次(做起点和终点分别1次),所以可以看成是二分图匹配。

    代码略丑:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <algorithm>
      8 #include <queue>
      9 
     10 using namespace std;
     11 
     12 template<const int _n>
     13 struct    Edge
     14 {
     15     struct Edge_base { int    to,next,w; }e[_n];
     16     int    cnt,p[_n];
     17     Edge() { clear(); }
     18     int    start(const int x) { return p[x]; }
     19     void    insert(const int x,const int y,const int z)
     20     { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
     21     Edge_base&    operator[](const int x) { return e[x]; }
     22     void    clear() { cnt=1,memset(p,0,sizeof(p)); }
     23 };
     24 
     25 int    n,m,SSS,TTT,Ans;
     26 int    level[310],cur[310],Out[310],to[310],from[310];
     27 bool    visited[310];
     28 Edge<15000>    e;
     29 
     30 bool    Bfs(const int S)
     31 {
     32     int    i,t;
     33     queue<int>    Q;
     34     memset(level,0,sizeof(level));
     35     level[S]=1;
     36     Q.push(S);
     37     while(!Q.empty())
     38     {
     39         t=Q.front();Q.pop();
     40         for(i=e.start(t);i;i=e[i].next)
     41         {
     42             if(!level[e[i].to] && e[i].w)
     43             {
     44                 level[e[i].to]=level[t]+1;
     45                 Q.push(e[i].to);
     46             }
     47         }
     48     }
     49     return level[TTT];
     50 }
     51 
     52 int    Dfs(const int S,const int bk)
     53 {
     54     if(S==TTT)return bk;
     55     int    rest=bk;
     56     for(int &i=cur[S];i;i=e[i].next)
     57     {
     58         if(level[e[i].to]==level[S]+1 && e[i].w)
     59         {
     60             int    flow=Dfs(e[i].to,min(e[i].w,rest));
     61             e[i].w-=flow;
     62             e[i^1].w+=flow;
     63             if((rest-=flow)<=0)break;
     64         }
     65     }
     66     if(bk==rest)level[S]=0;
     67     return bk-rest;
     68 }
     69 
     70 int    Dinic()
     71 {
     72     int    flow=0;
     73     while(Bfs(SSS))
     74     {
     75         memcpy(cur,e.p,sizeof(int)*(n+n+3));
     76         flow+=Dfs(SSS,0x3f3f3f3f);
     77     }
     78     return flow;
     79 }
     80 
     81 
     82 
     83 int main()
     84 {
     85     freopen("path3.in","r",stdin);
     86     freopen("path3.out","w",stdout);
     87     int    i,j,x,y;
     88 
     89     scanf("%d%d",&n,&m);
     90     for(i=1;i<=m;++i)
     91     {
     92         scanf("%d%d",&x,&y);
     93         e.insert(x,y+n,1);
     94         e.insert(y+n,x,0);
     95         Out[x]++;
     96     }
     97 
     98     SSS=n+n+1,TTT=n+n+2;
     99     for(i=1;i<=n;++i)
    100     {
    101         e.insert(SSS,i,1);
    102         e.insert(i,SSS,0);
    103         e.insert(i+n,TTT,1);
    104         e.insert(TTT,i+n,0);
    105     }
    106 
    107     Dinic();
    108 
    109     for(i=e.start(SSS);i;i=e[i].next)
    110     {
    111         if(e[i].w)continue;
    112         for(j=e.start(e[i].to);j;j=e[j].next)
    113         {
    114             if(e[j].to!=SSS && !e[j].w)
    115             {
    116                 to[e[i].to]=e[j].to-n;
    117                 from[e[j].to-n]=e[i].to;
    118                 break;
    119             }
    120         }
    121     }
    122 
    123     for(i=1;i<=n;++i)
    124     {
    125         if(!from[i])
    126         {
    127             int t=i;
    128             while(t)
    129             {
    130                 printf("%d ",t);
    131                 t=to[t];
    132             }
    133             printf("
    ");
    134             Ans++;
    135         }
    136     }
    137 
    138     printf("%d
    ",Ans);
    139 
    140     return 0;
    141 }
    View Code

    匈牙利写法详见:http://www.cnblogs.com/Ngshily/p/4988909.html

  • 相关阅读:
    突破
    leetcode刷题 538~
    leetcode刷题 519~
    Docker练习之镜像更新方法1
    十二 Linux之tar解压缩
    十一 Linux软件包管理yum
    十 Linux指令之grep
    九 linux指令之find
    八 Linux ps指令查看进程和kill杀进程
    七 Linux top命令
  • 原文地址:https://www.cnblogs.com/Gster/p/4989326.html
Copyright © 2011-2022 走看看