zoukankan      html  css  js  c++  java
  • 洛谷 P3376 【【模板】网络最大流】

    题目描述

    如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。

    输入

    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

    接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)

    输出

    一行,包含一个正整数,即为该网络的最大流。

    样例输入

    4 5 4 3
    4 2 30
    4 3 20
    2 3 20
    2 1 30
    1 3 40

    样例输出

    50

    数据规模:

    对于30%的数据:N<=10,M<=25

    对于70%的数据:N<=200,M<=1000

    对于100%的数据:N<=10000,M<=100000

    网络流的模板题。汇总一些增广路算法。(Ford-Fulkerson, Edmond-Karp, Dinic, ISAP)

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 using namespace std;
      7 
      8 struct edge {
      9     int to,cap,rev;
     10 };
     11 
     12 const int maxn=10001, INF=0x7F7F7F7F;
     13 int n,m;
     14 vector <edge> G[maxn+1];
     15 
     16 edge make_edge(int to, int cap, int rev) {
     17     edge x;
     18     x.to=to, x.cap=cap, x.rev=rev;
     19     return x;
     20 }
     21 
     22 void add_edge(int from, int to, int cap) {
     23     G[from].push_back(make_edge(to,cap,G[to].size()));
     24     G[to].push_back(make_edge(from,0,G[from].size()-1));
     25 }
     26 
     27 void init() {
     28     for (int i=1; i<=m; i++) {
     29         int u,v,w;
     30         scanf("%d%d%d",&u,&v,&w);
     31         add_edge(u,v,w);
     32     }
     33 }
     34 
     35 namespace Ford_Fulkerson {
     36     bool used[maxn+1];
     37 
     38     int dfs(int x, int t, int f) {
     39         if (x==t) return f;
     40         used[x]=true;
     41         for (int i=0; i<G[x].size(); i++) {
     42             edge &e=G[x][i];
     43             if (!used[e.to]&&e.cap>0) {
     44                 int d=dfs(e.to,t,min(f,e.cap));
     45                 if (d>0) {
     46                     e.cap-=d;
     47                     G[e.to][e.rev].cap+=d;
     48                     return d;
     49                 }
     50             }
     51         }
     52         return 0;
     53     }
     54 
     55     int max_flow(int s, int t) {
     56         int flow=0;
     57         for(;;) {
     58             memset(used,0,sizeof(used));
     59             int f=dfs(s,t,INF);
     60             if (f==0) return flow;
     61             flow+=f;
     62         }
     63     }
     64 }
     65 
     66 namespace Edmond_Karp {
     67     bool vis[maxn+1];
     68     int prev[maxn+1];
     69     int pree[maxn+1];
     70 
     71     void bfs(int s) {
     72         memset(vis,0,sizeof(vis));
     73         memset(prev,-1,sizeof(prev));
     74         memset(pree,-1,sizeof(pree));
     75         queue <int> q;
     76         vis[s]=true;
     77         q.push(s);
     78 
     79         while(!q.empty()) {
     80             int x=q.front();
     81             q.pop();
     82             for (int i=0; i<G[x].size(); i++) {
     83                 edge &e=G[x][i];
     84                 if (e.cap>0&&!vis[e.to]) {
     85                     prev[e.to]=x;
     86                     pree[e.to]=i;
     87                     vis[e.to]=true;
     88                     q.push(e.to);
     89                 }
     90             }
     91         }
     92     }
     93 
     94     int max_flow(int s, int t) {
     95         int flow=0;
     96         for(;;) {
     97             bfs(s);
     98             if (!vis[t]) return flow;
     99             int d=INF;
    100             for (int i=t; prev[i]!=-1; i=prev[i])
    101                 d=min(d,G[prev[i]][pree[i]].cap);
    102             for (int i=t; prev[i]!=-1; i=prev[i]) {
    103                 edge &e=G[prev[i]][pree[i]];
    104                 e.cap-=d;
    105                 G[e.to][e.rev].cap+=d;
    106             }
    107             flow+=d;
    108         }
    109     }
    110 }
    111 
    112 namespace Dinic {
    113     int level[maxn+1];
    114     int iter[maxn+1];
    115 
    116     void bfs(int s) {
    117         memset(level,-1,sizeof(level));
    118         queue <int> q;
    119         level[s]=0;
    120         q.push(s);
    121 
    122         while (!q.empty()) {
    123             int x=q.front();
    124             q.pop();
    125             for (int i=0; i<G[x].size(); i++) {
    126                 edge &e=G[x][i];
    127                 if (e.cap>0&&level[e.to]<0) {
    128                     level[e.to]=level[x]+1;
    129                     q.push(e.to);
    130                 }
    131             }
    132         }
    133     }
    134 
    135     int dfs(int x, int t, int f) {
    136         if (x==t) return f;
    137         for (int &i=iter[x]; i<G[x].size(); i++) {
    138             edge &e=G[x][i];
    139             if (e.cap>0&&level[e.to]>level[x]) {
    140                 int d=dfs(e.to,t,min(f,e.cap));
    141                 if (d>0) {
    142                     e.cap-=d;
    143                     G[e.to][e.rev].cap+=d;
    144                     return d;
    145                 }
    146             }
    147         }
    148         return 0;
    149     }
    150 
    151     int max_flow(int s, int t) {
    152         int flow=0;
    153         for(;;) {
    154             bfs(s);
    155             if (level[t]<0) return flow;
    156             memset(iter,0,sizeof(iter));
    157             int f;
    158             while ((f=dfs(s,t,INF))>0)
    159                 flow+=f;
    160         }
    161     }
    162 }
    163 
    164 namespace ISAP {
    165     int gap[maxn+1];
    166     int iter[maxn+1];
    167     int level[maxn+1];
    168 
    169     void bfs(int t) {
    170         memset(gap,0,sizeof(gap));
    171         memset(level,-1,sizeof(level));
    172         queue <int> q;
    173         level[t]=1;
    174         gap[level[t]]=1;
    175         q.push(t);
    176 
    177         while (!q.empty()) {
    178             int x=q.front();
    179             q.pop();
    180             for (int i=0; i<G[x].size(); i++) {
    181                 edge &e=G[x][i];
    182                 if (level[e.to]<0) {
    183                     level[e.to]=level[x]+1;
    184                     gap[level[e.to]]++;
    185                     q.push(e.to);
    186                 }
    187             }
    188         }
    189     }
    190 
    191     int dfs(int x, int s, int t, int f) {
    192         if (x==t) return f;
    193         int flow=0;
    194         for (int &i=iter[x]; i<G[x].size(); i++) {
    195             edge &e=G[x][i];
    196             if (e.cap>0&&level[x]==level[e.to]+1) {
    197                 int d=dfs(e.to,s,t,min(f-flow,e.cap));
    198                 e.cap-=d;
    199                 G[e.to][e.rev].cap+=d;
    200                 flow+=d;
    201                 if (f==flow) return f;
    202             }
    203         }
    204 
    205         gap[level[x]]--;
    206         if (gap[level[x]]==0)
    207             level[s]=n+1;
    208         iter[x]=0;
    209         gap[++level[x]]++;
    210         return flow;
    211     }
    212 
    213     int max_flow(int s, int t) {
    214         int flow=0;
    215         bfs(t);
    216         memset(iter,0,sizeof(iter));
    217         while (level[s]<=n)
    218             flow+=dfs(s,s,t,INF);
    219         return flow;
    220     }
    221 }
    222 
    223 int main() {
    224     int s,t;
    225     scanf("%d%d%d%d",&n,&m,&s,&t);
    226     init();
    227     printf("%d
    ",ISAP::max_flow(s,t));
    228     return 0;
    229 }
  • 相关阅读:
    光棒效果的几种方法
    jQuery中的事件与动画
    jQuery中.bind() .live() .delegate() .on()的区别
    JavaScript基础
    jQuery选择器课堂随笔
    Leetcode_34【在排序数组中查找元素的第一个和最后一个位置】
    Leetcode_33【搜索旋转排序数组】
    Leetcode_32【最长有效括号】
    Leetcode_31【下一个排列】
    Leetcode_30【串联所有单词的子串】
  • 原文地址:https://www.cnblogs.com/tweetuzki/p/8413660.html
Copyright © 2011-2022 走看看