• POJ 1273 Drainage Ditches【最大流模版】


    题意:现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条有向水渠,给出这n条水渠所连接的点和所能流过的最大流量,求从源点到汇点能流过的最大流量

    Dinic

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include <cstdio>
     5 #include <queue>
     6 using namespace std;
     7 const int N = 202;
     8 const int INF = 0x3f3f3f3f;
     9 int m,n,tot;
    10 int head[N],level[N];
    11 struct node
    12 {
    13     int t,next,w;
    14 }edge[N<<2];
    15 
    16 
    17 void init()
    18 {
    19     tot=-1;
    20     memset(head,-1, sizeof(head));
    21 }
    22 
    23 void add(int s,int t,int w)
    24 {
    25     edge[++tot].t=t,edge[tot].w=w,edge[tot].next=head[s],head[s]=tot;
    26     edge[++tot].t=s,edge[tot].w=0,edge[tot].next=head[t],head[t]=tot;
    27 }
    28 
    29 bool bfs()
    30 {
    31     memset(level,0,sizeof(level));
    32     queue<int> q;
    33     while(!q.empty())q.pop();
    34     q.push(1);
    35     level[1]=1;
    36     while(q.size())
    37     {
    38         int u=q.front();q.pop();
    39         for(int i=head[u];i!=-1;i=edge[i].next)
    40         {
    41             if(edge[i].w>0&&level[edge[i].t]==0)
    42             {
    43                 q.push(edge[i].t);
    44                 level[edge[i].t]=level[u]+1;
    45             }
    46             if(level[m]!=0)return 1;
    47         }
    48     }
    49     return 0;
    50 }
    51 
    52 int dfs(int s,int t, int flow)
    53 {
    54     if(s==t)return flow;
    55     for(int i=head[s];i!=-1;i=edge[i].next)
    56     {
    57         if(edge[i].w>0&&level[edge[i].t]==level[s]+1)
    58         {
    59             int k = dfs(edge[i].t,t,min(flow,edge[i].w));
    60             if(k>0)
    61             {
    62                 edge[i].w-=k;
    63                 edge[i^1].w+=k;
    64                 return k;
    65             }
    66         }
    67     }
    68     return 0;
    69 }
    70 //
    71 void dinic()
    72 {
    73     int flow=0;
    74     while(bfs()) // 寻找最短增广路,分层图
    75     {
    76         int f=0;
    77         while((f=dfs(1,m,INF))>0)flow+=f; // 在分层图上增广
    78     }
    79     cout<<flow<<endl;
    80 }
    81 int main()
    82 {
    83     while(~scanf("%d%d",&n,&m))
    84     {
    85         init();
    86         while(n--)
    87         {
    88             int a,b,c;
    89             scanf("%d%d%d",&a,&b,&c);
    90             add(a,b,c);
    91         }
    92         dinic();
    93     }
    94     return 0;
    95 }

    建图的另一种方法,上面有两种邻接表的方法,一种是单纯用数组模拟,可以运用异或操作反向边;另一个是vector模拟,反向边做特别记录

     1 struct edge
     2 {
     3     int to,cap,rev;// 反向边
     4 };
     5 vector<edge> g[maxn];
     6 int level[maxn];
     7 
     8 void add_edge(int from,int to,int cap)
     9 {
    10     //最后一个元素是反向边的索引,便于快速查找
    11     g[from].push_back((edge){to,cap,g[to].size()}); 
    12     g[to].push_back((edge){from,0,g[from].size()-1});
    13 }

    Ford_Fulkerson

  • 相关阅读:
    CodeForces 156B Suspects(枚举)
    CodeForces 156A Message(暴力)
    CodeForces 157B Trace
    CodeForces 157A Game Outcome
    HDU 3578 Greedy Tino(双塔DP)
    POJ 2609 Ferry Loading(双塔DP)
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛十六进制转换成十进制
  • 原文地址:https://www.cnblogs.com/demian/p/9219318.html
Copyright © 2020-2023  润新知