zoukankan      html  css  js  c++  java
  • 网络流学习笔记

    网络流问题,主要是给你一张网络,让你所流的水量最大。

    主要用于求最大流问题。

    网络流的相关定义:

    • 源点:有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点
    • 汇点:另一个点也很特殊,只进不出,叫做汇点
    • 容量和流量:每条有向边上有两个量,容量和流量,从i到j的容量通常用c[i,j]表示,流量则通常是f[i,j].

    通常可以把这些边想象成道路,流量就是这条道路的车流量,容量就是道路可承受的最大的车流量。很显然的,流量<=容量。而对于每个不是源点和汇点的点来说,可以类比的想象成没有存储功能的货物的中转站,所有“进入”他们的流量和等于所有从他本身“出去”的流量。

    • 最大流:把源点比作工厂的话,问题就是求从工厂最大可以发出多少货物,是不至于超过道路的容量限制,也就是,最大流

    求解思路:

    • (1).寻找增广路的时候我们可以简单的从源点开始做BFS,并不断修改这条路上的delta 量,直到找到源点或者找不到增广路。
    • (2).在程序实现的时候,我们通常只是用一个c 数组来记录容量,而不记录流量,当流量+delta 的时候,我们可以通过容量-delta 来实现,以方便程序的实现。

     为什么要建反向边?退流操作,如果在寻找增光路时需要回流,可以利用反向边进行回流

     操作步骤: 

    • 现用bfs寻找增光路,如果可以寻找到,则dfs求值

    代码(dinic)

     1 #include<bits/stdc++.h>
     2 #define N 10000010
     3 using namespace std;
     4 struct edge
     5 {
     6     int now,next,to,f;
     7 }e[N];
     8 int n,m,head[N],lev[N],cur[N],tot=1,st,en;
     9 inline void add(int x,int y,int z)
    10 {
    11     e[++tot].next=head[x];
    12     head[x]=tot;
    13     e[tot].now=x;
    14     e[tot].to=y;
    15     e[tot].f=z;
    16 }
    17 inline int bfs()
    18 {
    19     queue<int>q;
    20     memset(lev,0,sizeof(lev));
    21     q.push(st);
    22     lev[st]=1;
    23     while(!q.empty())
    24     {
    25         int u=q.front();
    26         q.pop();
    27         for(int i=head[u];i!=-1;i=e[i].next)
    28         {
    29             int v=e[i].to;
    30             if(lev[v]==0 && e[i].f)
    31             {
    32                 lev[v]=lev[u]+1;
    33                 q.push(v);
    34             }
    35         }
    36     }
    37     return lev[en];
    38 }
    39 int dfs(int now,int a)
    40 {
    41     if(now == en || a<=0)
    42         return a;
    43     int flow=0,fl;
    44     for(int &i=cur[now];i!=-1;i=e[i].next)
    45     {
    46         int v=e[i].to;
    47         if(e[i].f && lev[v]==lev[e[i].now]+1)
    48         {
    49             fl=dfs(e[i].to,min(a,e[i].f));
    50             e[i].f-=fl;
    51             e[i^1].f+=fl;
    52             flow+=fl;
    53             a-=fl;
    54             if(a<=0)
    55                 break;
    56         }
    57     }
    58     return flow;
    59 }
    60 void dinic()
    61 {
    62     int ans=0;
    63     while(bfs())
    64     {
    65         for(int i=1;i<=n;i++)cur[i]=head[i];
    66         ans+=dfs(st,0x7fffffff);
    67     }
    68     cout<<ans;
    69 }
    70 int main()
    71 {
    72     memset(head,-1,sizeof(head));
    73     cin >> n >> m >> st >> en;
    74     for(int i=1;i<=m;i++)
    75     {
    76         int a,b,c;
    77         cin >> a >> b >> c;
    78         add(a,b,c);
    79         add(b,a,0);
    80     }
    81     dinic();
    82     return 0;
    83 }
    View Code

    模板题

  • 相关阅读:
    Powershell数据处理
    Powershell About Active Directory Group Membership of a domain user
    Powershell About Active Directory Server
    Oracle Schema Objects——Tables——TableStorage
    Oracle Schema Objects——Tables——TableType
    English Grammar
    Oracle Database Documentation
    Oracle Schema Objects——Tables——Oracle Data Types
    Oracle Schema Objects——Tables——Overview of Tables
    What is Grammar?
  • 原文地址:https://www.cnblogs.com/ifmyt/p/9424714.html
Copyright © 2011-2022 走看看