zoukankan      html  css  js  c++  java
  • [Luogu] P3376 模板-网络流-最大流

    题目描述

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

    输入输出格式

    输入格式:

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

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    4 5 4 3
    4 2 30
    4 3 20
    2 3 20
    2 1 30
    1 3 40
    输出样例#1:
    50

    说明

    时空限制:1000ms,128M

    数据规模:

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

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

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

    样例说明:

    题目中存在3条路径:

    4-->2-->3,该路线可通过20的流量

    4-->3,可通过20的流量

    4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)

    故流量总计20+20+10=50。输出50。

    分析

    这是一个单纯的题目,优化都不用

    = =然而我是对着刘汝佳写过去的

    网络流还是推荐紫书

    代码

     1 //事先声明,这份代码并不是原创,只是将刘汝佳的进行风格转化
     2 //数组模拟版本邻接表= =刘汝佳写的虽然简练但是我不是很习惯
     3 #include<cstdio>
     4 #include<iostream>
     5 #include<queue>
     6 #include<cstring>
     7 #define maxn 10000000
     8 using namespace std;
     9 
    10 int inf = 2139999999;
    11 
    12 struct edge{
    13     int from,u,v,cup,flow;
    14 }e[maxn];
    15 
    16 int tot = 2,first[maxn*4];
    17 void insert(int u,int v,int ccup){
    18     e[tot].from = first[u];
    19     e[tot].u = u;
    20     e[tot].v = v;
    21     e[tot].cup = ccup;
    22     e[tot].flow = 0;
    23     first[u] = tot;
    24     tot++;
    25     
    26     e[tot].from = first[v];
    27     e[tot].u = v;
    28     e[tot].v = u;
    29     e[tot].cup = e[tot].flow = 0;
    30     first[v] = tot;
    31     tot++;
    32 }
    33 
    34 int pre[maxn],s,t,a[maxn],n,m;
    35 int maxflow(int s,int t){
    36     
    37     int flow = 0;
    38     while(true){
    39 //        cout << "gua!  ";
    40         memset(a,0,sizeof(a));
    41         queue<int> Q;
    42         Q.push(s);
    43         a[s] = inf;
    44         while(!Q.empty()){
    45 //            cout << "Meow!  ";
    46             int p = Q.front(); Q.pop();
    47             
    48             for(int i = first[p];i;i = e[i].from){
    49                 edge &E = e[i];
    50                 if(!a[E.v] && E.flow < E.cup){
    51                     pre[E.v] = i;
    52                     a[E.v] = min(a[p],E.cup-E.flow);
    53                     Q.push(E.v);
    54                 }
    55             }
    56             
    57             if(a[t]) break;
    58         }
    59         
    60         if(!a[t]) break;
    61         
    62         for(int u = t;u != s;u = e[pre[u]].u){
    63             e[pre[u]].flow += a[t];
    64             e[pre[u]^1].flow -= a[t];
    65         }
    66         
    67         flow += a[t];
    68     }
    69     
    70 //    for(int i = 0;i <= n;i++){
    71 //        printf("%d ",a[i]);
    72 //    }cout << endl;
    73     
    74     return flow;
    75 }
    76 
    77 int main(){
    78     scanf("%d%d%d%d",&n,&m,&s,&t);
    79     
    80     for(int i = 1;i <= m;i++){
    81         int u,v,ccup;
    82         scanf("%d%d%d",&u,&v,&ccup);
    83         insert(u,v,ccup);
    84     } 
    85     
    86     cout << maxflow(s,t);
    87     
    88 //    for(int i = 0;i <= tot;i++){
    89 //        printf("%d %d %d %d %d
    ",e[i].from,e[i].u,e[i].v,e[i].cup,e[i].flow);
    90 //    }
    91     
    92     return 0;
    93 } 
    心情仍然奇差无比
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    TCP/IP学习笔记:组播
    使用WITH AS 优化SQL
    帮盖尔优化SQL子查询优化的经典案例
    帮盖尔优化SQL
    子查询里面有树形查询,子查询选择使用in/exists需要特别留意
    [Linux] 服务器性能调优(CPU绑定)
    TCP/IP学习笔记:RIP
    TCP/IP学习笔记:路由与BGP
    利用Merge代替复杂的UPDATE语句
    android开机启动流程说明
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7430090.html
Copyright © 2011-2022 走看看