zoukankan      html  css  js  c++  java
  • 我爱网络流之最大流Dinic

    直接上大佬博客:

    Dinic算法详解及实现来自小菲进修中

    Dinic算法(研究总结,网络流)来自SYCstudio

      模板步骤:

      第一步,先bfs把图划分成分成分层图网络

      第二步,dfs多次找增广路

      当前弧优化:即每一次dfs增广时不从第一条边开始,而是用一个数组cur记录点u之前循环到了哪一条边,以此来加速

    POJ - 1273 Drainage Ditches

       裸的最大流,直接按题意建图跑就行

     1 #include<cstdio>
     2 #include<queue>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=218,inf=2000000007;
     6 struct Side{
     7     int v,ne,w;
     8 }S[N<<1];
     9 int n,sn,head[N],cur[N],dep[N];
    10 void init()
    11 {
    12     sn=0;
    13     for(int i=0;i<=n;i++)
    14         head[i]=-1;
    15 }
    16 void add(int u,int v,int w)
    17 {
    18     S[sn].v=v;
    19     S[sn].w=w;
    20     S[sn].ne=head[u];
    21     head[u]=sn++;
    22 }
    23 void addE(int u,int v,int w)
    24 {
    25     add(u,v,w);
    26     add(v,u,0);
    27 }
    28 bool bfs()
    29 {
    30     queue<int> q;
    31     for(int i=0;i<=n;i++)
    32         dep[i]=0;
    33     dep[1]=1;
    34     q.push(1);
    35     int x,y;
    36     while(!q.empty())
    37     {
    38         x=q.front();
    39         q.pop();
    40         for(int i=head[x];~i;i=S[i].ne)
    41         {
    42             y=S[i].v;
    43             if(S[i].w>0&&!dep[y])
    44             {
    45                 dep[y]=dep[x]+1;
    46                 q.push(y);
    47             }
    48         }
    49     }
    50     return dep[n]!=0;
    51 }
    52 int dfs(int u,int minf)
    53 {
    54     if(u==n||!minf)
    55         return minf;
    56     int v,flow;
    57     for(int &i=cur[u];~i;i=S[i].ne)
    58     {
    59         v=S[i].v;
    60         if(dep[v]==dep[u]+1&&S[i].w>0)
    61         {
    62             flow=dfs(v,min(minf,S[i].w));
    63             if(flow)
    64             {
    65                 S[i].w-=flow;
    66                 S[i^1].w+=flow;
    67                 return flow;
    68             }
    69         }
    70     }
    71     return 0;
    72 }
    73 int dinic()
    74 {
    75     int ans=0,flow;
    76     while(bfs())
    77     {
    78         for(int i=1;i<=n;i++)
    79             cur[i]=head[i];
    80         while(flow=dfs(1,inf))
    81             ans+=flow;
    82     }
    83     return ans;
    84 }
    85 int main()
    86 {
    87     int m,u,v,w;
    88     while(~scanf("%d%d",&m,&n))
    89     {
    90         init();
    91         while(m--)
    92         {
    93             scanf("%d%d%d",&u,&v,&w);
    94             addE(u,v,w);
    95         }
    96         printf("%d
    ",dinic());
    97     }
    98     return 0;
    99 }
    小桥流水人家

    POJ - 1698Alice's Chance

      也是个裸的最大流,不过得看得出来,就把每周每天视为节点,然后弄个汇点跟源点,跑一遍dinic看最大流是不是总要求的天数

      1 #include<cstdio>
      2 #include<queue>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=6118,inf=2000000007;
      6 struct Side{
      7     int v,ne,w;
      8 }S[N<<1];
      9 struct Film{
     10     int ok[8],day,week;
     11 }F[N];
     12 int n,sn,sum,sb,se,head[N],cur[N],dep[N];
     13 void init()
     14 {
     15     sn=0,sum=0;
     16     sb=0,se=n+351;
     17     for(int i=0;i<=se;i++)
     18         head[i]=-1;
     19 }
     20 void add(int u,int v,int w)
     21 {
     22     S[sn].v=v;
     23     S[sn].w=w;
     24     S[sn].ne=head[u];
     25     head[u]=sn++;
     26 }
     27 void addE(int u,int v,int w)
     28 {
     29     add(u,v,w);
     30     add(v,u,0);
     31 }
     32 bool bfs()
     33 {
     34     queue<int> q;
     35     for(int i=0;i<=se;i++)
     36         dep[i]=0;
     37     dep[sb]=1;
     38     q.push(sb);
     39     int u,v;
     40     while(!q.empty())
     41     {
     42         u=q.front();
     43         q.pop();
     44         for(int i=head[u];~i;i=S[i].ne)
     45         {
     46             v=S[i].v;
     47             if(S[i].w>0&&!dep[v])
     48             {
     49                 dep[v]=dep[u]+1;
     50                 q.push(v); 
     51             }
     52         }
     53     }
     54     return dep[se]!=0;
     55 }
     56 int dfs(int u,int minf)
     57 {
     58     if(u==se||!minf)
     59         return minf;
     60     int v,flow;
     61     for(int &i=cur[u];~i;i=S[i].ne)
     62     {
     63         v=S[i].v;
     64         if(S[i].w>0&&dep[v]==dep[u]+1)
     65         {
     66             flow=dfs(v,min(minf,S[i].w));
     67             if(flow>0)
     68             {
     69                 S[i].w-=flow;
     70                 S[i^1].w+=flow;
     71                 return flow;
     72             }
     73         }
     74     }
     75     return 0;
     76 }
     77 int dinic()
     78 {
     79     int ans=0,flow;
     80     while(bfs())
     81     {
     82         for(int i=0;i<=se;i++)
     83             cur[i]=head[i];
     84         while(flow=dfs(sb,inf))
     85             ans+=flow;
     86     }
     87     return ans;
     88 }
     89 int main()
     90 {
     91     int t;
     92     scanf("%d",&t);
     93     while(t--)
     94     {
     95         scanf("%d",&n);
     96         init();
     97         for(int i=1;i<=n;i++)
     98         {
     99             for(int j=1;j<=7;j++)
    100                 scanf("%d",&F[i].ok[j]);
    101             scanf("%d%d",&F[i].day,&F[i].week);
    102             sum+=F[i].day;
    103         }
    104         for(int i=1;i<=n;i++)
    105             addE(sb,i,F[i].day);
    106         for(int i=1;i<=n;i++)
    107         {
    108             for(int j=0;j<F[i].week;j++)
    109                 for(int k=1;k<=7;k++)
    110                     if(F[i].ok[k])
    111                         addE(i,n+j*7+k,1);
    112         }
    113         for(int i=0;i<50;i++)
    114             for(int j=1;j<=7;j++)
    115                 addE(n+i*7+j,se,1);
    116         if(dinic()>=sum)
    117             printf("Yes
    ");
    118         else
    119             printf("No
    ");
    120     }
    121     return 0;
    122 }
    one day day

    HDU 3605Escape

      100000个人,但才10个星球,在建图上,把可以去的星球状态相同的人视为一样的,这样最多就才1024个状态,然后跑一遍dinic,c++直接交,g++的话得用快读。

      1 #include<cstdio>
      2 #include<queue>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=1<<12,inf=1000000007;
      6 struct Side{
      7     int v,ne,w;
      8 }S[N<<2];
      9 int sn,pb,pe,n,m,head[N],cur[N];
     10 int cf2[12]={1},man[N],dep[N];
     11 //int read()
     12 //{
     13 //    int res = 0, flg = 1; char chr = getchar();
     14 //    while(chr < '0' || chr > '9') {if(chr == '-') res = -1; chr = getchar();}
     15 //    while(chr <= '9' && chr >= '0') {res = res * 10 + chr - '0'; chr = getchar();}
     16 //    return res * flg;
     17 //}g++用快读 
     18 void init()
     19 {
     20     sn=0;
     21     pb=0,pe=cf2[m]+m;
     22     for(int i=0;i<cf2[m];i++)
     23         man[i]=0;
     24     for(int i=0;i<=pe;i++)
     25         head[i]=-1;
     26 }
     27 void add(int u,int v,int w)
     28 {
     29     S[sn].w=w;
     30     S[sn].v=v;
     31     S[sn].ne=head[u];
     32     head[u]=sn++; 
     33 }
     34 void addE(int u,int v,int w)
     35 {
     36     add(u,v,w);
     37     add(v,u,0);
     38 }
     39 bool bfs()
     40 {
     41     for(int i=0;i<=pe;i++)
     42         dep[i]=0;
     43     dep[pb]=1;
     44     queue<int> q;
     45     q.push(pb);
     46     int u,v;
     47     while(!q.empty())
     48     {
     49         u=q.front();
     50         q.pop();
     51         for(int i=head[u];~i;i=S[i].ne)
     52         {
     53             v=S[i].v;
     54             if(S[i].w>0&&!dep[v])
     55             {
     56                 dep[v]=dep[u]+1;
     57                 q.push(v);
     58             }
     59         }
     60     }
     61     return dep[pe]!=0;
     62 }
     63 int dfs(int u,int minf)
     64 {
     65     if(u==pe||!minf)
     66         return minf;
     67     int v,flow;
     68     for(int &i=cur[u];~i;i=S[i].ne)
     69     {
     70         v=S[i].v;
     71         if(S[i].w>0&&dep[v]==dep[u]+1)
     72         {
     73             flow=dfs(v,min(minf,S[i].w));
     74             if(flow)
     75             {
     76                 S[i].w-=flow;
     77                 S[i^1].w+=flow;
     78                 return flow;
     79             }
     80         }
     81     }
     82     return 0;
     83 }
     84 int dinic()
     85 {
     86     int maxf=0,flow;
     87     while(bfs())
     88     {
     89         for(int i=0;i<=pe;i++)
     90             cur[i]=head[i];
     91         while(flow=dfs(pb,inf))
     92             maxf+=flow;
     93     }
     94     return maxf;
     95 }
     96 int main()
     97 {
     98     for(int i=1;i<=10;i++)
     99         cf2[i]=cf2[i-1]<<1;
    100     int num,x;
    101     while(~scanf("%d%d",&n,&m))
    102     {
    103         init();
    104         for(int i=1;i<=n;i++)
    105         {
    106             num=0;
    107             for(int j=0;j<m;j++)
    108             {
    109                 scanf("%d",&x);
    110                 if(x)
    111                     num|=cf2[j];
    112             }
    113             man[num]++;
    114         }
    115         for(int i=1;i<cf2[m];i++)
    116             if(man[i])
    117             {
    118                 addE(pb,i,man[i]);
    119                 for(int j=0;j<m;j++)
    120                     if(i&cf2[j])
    121                         addE(i,cf2[m]+j,man[i]);
    122             }
    123         for(int i=0;i<m;i++)
    124         {
    125             scanf("%d",&x);
    126             addE(cf2[m]+i,pe,x);
    127         }
    128         if(dinic()>=n)
    129             printf("YES
    ");
    130         else
    131             printf("NO
    ");
    132     }
    133     return 0;
    134 }
    流浪星球

      啊,网络流就在于建图。

  • 相关阅读:
    第二章 Java浮点数精确计算
    第一章 Java代码执行流程
    第九章 JVM调优推荐
    第八章 JVM性能监控与故障处理工具(2)
    基于Redis构建10万+终端级的高性能部标JT808协议的Gps网关服务器(转)
    基于Java Netty框架构建高性能的Jt808协议的GPS服务器(转)
    Netty(七):流数据的传输处理
    Java中的位运算符
    二进制(原码、反码、补码)
    Java数据结构和算法(二):数组
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11003929.html
Copyright © 2011-2022 走看看