zoukankan      html  css  js  c++  java
  • P3376 【模板】网络最大流dinic算法

     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。

    分析

    dinic算法,需要注意许多点:

    • 反向边初始值容量为0,
    • 异或符号,x^1,x为偶数+1,奇数-1;所以第一条边为偶数,所以我的第一条边是2,他的反向边是3;
    • 数据范围,这个就不多说了,反向建边,数组大小要乘2

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 const int N = 20100;
     7 const int INF = 1e9;
     8 
     9 struct Edge{
    10     int to,c,nxt;
    11 }e[500100];
    12 
    13 int q[5000100],head[N],dis[N],cur[N];
    14 int S,T,n,m,L,R,tot = 1;
    15 
    16 inline char nc() {
    17     static char buf[100000],*p1 = buf,*p2 = buf;
    18     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
    19 }
    20 inline int read() {
    21     int x = 0,f = 1;char ch = nc();
    22     for (; ch<'0'||ch>'9'; ch = nc()) if (ch=='-') f = -1;
    23     for (; ch>='0'&&ch<='9'; ch = nc()) x = x * 10 + ch - '0';
    24     return x * f;
    25 }
    26 inline void add_edge(int u,int v,int w) {
    27     e[++tot].to = v,e[tot].c = w,e[tot].nxt = head[u],head[u] = tot;
    28     e[++tot].to = u,e[tot].c = 0,e[tot].nxt = head[v],head[v] = tot;
    29 }
    30 inline bool bfs() {
    31     for (int i=1; i<=n; ++i) {
    32         cur[i] = head[i];dis[i] = -1;
    33     }
    34     L = 1;R = 0;
    35     q[++R] = S;
    36     dis[S] = 0;
    37     while (L <= R) {
    38         int u = q[L++];
    39         for (int i=head[u]; i; i=e[i].nxt) {
    40             int v = e[i].to,c = e[i].c;
    41             if (dis[v]==-1 && c>0) {
    42                 q[++R] = v;
    43                 dis[v] = dis[u] + 1;
    44                 if (v==T) return true;
    45             }
    46         }
    47     }
    48     return false;
    49 }
    50 int dfs(int u,int flow) {
    51     if (u==T) return flow;
    52     int used = 0;
    53     for (int & i=cur[u]; i; i=e[i].nxt) {
    54         int v = e[i].to,c = e[i].c;
    55         if (dis[v]==dis[u]+1 && c>0) {
    56             int tmp = dfs(v,min(c,flow-used));
    57             if (tmp > 0) {
    58                 e[i].c -= tmp;e[i^1].c += tmp;
    59                 used += tmp;
    60                 if (used==flow) break;
    61             }
    62         } 
    63     }
    64     if (used != flow) dis[u] = -1;
    65     return used;
    66 }
    67 inline int dinic() {
    68     int ans = 0;
    69     while (bfs())
    70         ans += dfs(S,INF);
    71     return ans;
    72 }
    73 int main() {
    74     n = read(),m = read(),S = read(),T = read();
    75     for (int a,b,c,i=1; i<=m; ++i) {
    76         a = read(),b = read(),c = read();
    77         add_edge(a,b,c);
    78     }
    79     printf("%d",dinic());
    80     return 0;
    81 }
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 using namespace std;
     6 
     7 const int MAXN = 100100;
     8 const int INF = 1e9;
     9 
    10 struct Edge{
    11     int to,c,nxt;
    12     Edge(){}
    13     Edge(int tt,int cc,int nn) {to = tt,c = cc,nxt = nn;}
    14 }e[1000100];
    15 queue<int>q;
    16 
    17 int head[MAXN],dis[MAXN];
    18 int s,t,n,m,tot = 1;
    19 
    20 int read()
    21 {
    22     int x = 0, f = 1;char ch = getchar();
    23     while (ch<'0'||ch>'9') {if (ch=='-') f = -1; ch = getchar();}
    24     while (ch>='0'&&ch<='9') {x = x*10+ch-'0'; ch = getchar();}
    25     return x*f;
    26 }
    27 bool bfs()
    28 {
    29     q.push(s);
    30     memset(dis,-1,sizeof(dis));
    31     dis[s] = 0;
    32     while (!q.empty())
    33     {
    34         int u = q.front();
    35         q.pop();
    36         for (int i=head[u]; i; i=e[i].nxt)
    37         {
    38             int v = e[i].to;
    39             if (dis[v]==-1&&e[i].c>0)
    40             {
    41                 dis[v] = dis[u]+1;
    42                 q.push(v);
    43             }
    44         }
    45     }
    46     if (dis[t]!=-1) return true;
    47     return false;
    48 }
    49 int dfs(int u,int low)
    50 {
    51     if (u==t) return low;
    52     int w,used = 0;
    53     for (int i=head[u]; i; i=e[i].nxt)
    54     {
    55         int v = e[i].to;
    56         if (dis[v]==dis[u]+1&&e[i].c>0)
    57         {
    58             w = dfs(v,min(low-used,e[i].c));
    59             e[i].c -= w;
    60             e[i^1].c += w;
    61             used += w;
    62             if (used==low) return low;
    63         }
    64     }
    65     if (!used) dis[u] = -1;
    66     return used;
    67 }
    68 int dinic()
    69 {
    70     int ans = 0,t;
    71     while (bfs())
    72         ans += dfs(s,INF);
    73     return ans;
    74 }
    75 int main()
    76 {
    77     n = read();m = read();s = read();t = read();
    78     for (int u,v,w,i=1; i<=m; ++i)
    79     {
    80         u = read();v = read();w = read();
    81         e[++tot] = Edge(v,w,head[u]);
    82         head[u] = tot;
    83         e[++tot] = Edge(u,0,head[v]);
    84         head[v] = tot;    
    85     }
    86     printf("%d",dinic());
    87     return 0;
    88 }
    很早以前的代码
  • 相关阅读:
    数组,集合,泛型
    DataSet和实体,泛型集合
    数据源绑定控件的Row/ItemDataBound事件
    Access 中时间格式 yyyyMMdd HH:mm:ss
    IMG标记的alt属性和title属性详解
    后台代码(cs)中加空格
    数据绑定控件之绑定项
    数据绑定控件之DataBound事件
    DataSet,DataTable,DateView的关系和用法
    程序编程网
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7256796.html
Copyright © 2011-2022 走看看