P3376 【模板】网络最大流(70)

题目描述

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

输入输出格式

输入格式:

第一行包含四个正整数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。

莫名其妙WA三个点,

改天再调

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<queue>
  6 #include<algorithm>
  7 #define lli long long int
  8 using namespace std;
  9 const int MAXN=300001;
 10 const int maxn=0x7ffffff;
 11 void read(int &n)
 12 {
 13     char c=‘+‘;int x=0;bool flag=0;
 14     while(c<‘0‘||c>‘9‘)
 15     {c=getchar();if(c==‘-‘)flag=1;}
 16     while(c>=‘0‘&&c<=‘9‘)
 17     {x=x*10+c-48;c=getchar();}
 18     flag==1?n=-x:n=x;
 19 }
 20 struct node
 21 {
 22     int u,v,flow,cap,nxt;
 23 }edge[MAXN];
 24 int head[MAXN];
 25 int num=1;
 26 int n,m,S,T;
 27 int dis[MAXN];
 28 int vis[MAXN];
 29 int cur[MAXN];
 30 void add_edge(int x,int y,int z)
 31 {
 32     edge[num].u=x;
 33     edge[num].v=y;
 34     edge[num].cap=z;
 35     edge[num].flow=0;
 36     edge[num].nxt=head[x];
 37     head[x]=num++;
 38 }
 39 bool bfs(int bg,int ed)
 40 {
 41     memset(vis,0,sizeof(vis));
 42     memset(dis,0,sizeof(dis));
 43     queue<int>q;
 44     q.push(bg);
 45     dis[bg]=1;
 46     vis[bg]=1;
 47     while(!q.empty())
 48     {
 49         int p=q.front();
 50         q.pop();
 51         for(int i=head[p];i!=-1;i=edge[i].nxt)
 52         {
 53             if(!vis[edge[i].v]&&edge[i].cap-edge[i].flow>0)
 54             {
 55                 vis[edge[i].v]=1;
 56                 dis[edge[i].v]=dis[edge[i].u]+1;
 57                   q.push(edge[i].v);
 58             }
 59         }
 60     }
 61     return vis[ed];
 62 }
 63 int dfs(int now,int a)// a:所有弧的最小残量
 64 {
 65     if(now==T||a<=0)
 66         return a;
 67     int flow=0,f;
 68     for(int i=head[now];i!=-1;i=edge[i].nxt)
 69     {
 70         if(dis[now]+1==dis[edge[i].v]&&edge[i].cap-edge[i].flow>0)
 71         {
 72             f=dfs(edge[i].v,min(a,edge[i].cap-edge[i].flow));
 73             edge[i].flow+=f;
 74             edge[i^1].flow-=f;
 75             flow+=f;
 76             a-=f;
 77             if(a<=0)break;
 78         }
 79     }
 80     return flow;
 81 }
 82 void Dinic(int S,int T)
 83 {
 84     int ansflow=0;
 85     //for(int i=1;i<=n;i++)
 86     //        cur[i]=head[i];
 87     while(bfs(S,T))
 88     {
 89         ansflow+=dfs(S,maxn);
 90     }// 求出层级
 91     printf("%d",ansflow);
 92
 93 }
 94 int main()
 95 {
 96     read(n);read(m);
 97 //    swap(n,m);
 98 //    S=1;T=m;
 99     read(S);read(T);
100     for(int i=1;i<=n;i++)
101         head[i]=-1;
102     for(int i=1;i<=m;i++)
103     {
104         int x,y,z;
105         read(x);read(y);read(z);
106         add_edge(x,y,z);
107         add_edge(y,x,0);
108     }
109     Dinic(S,T);
110     return 0;
111 }
时间: 2024-10-11 16:54:03

P3376 【模板】网络最大流(70)的相关文章

洛谷 P3376 【模板】网络最大流

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

洛谷 P3376 【模板】网络最大流 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problemnew/show/3376 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正

洛谷 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<=2

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

P3376 【模板】网络最大流

https://www.luogu.org/problem/show?pid=3376#sub 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正整数,即为该网络的最大流. 输入输出样例 输入样例#1: 4 5 4

算法模板——Dinic网络最大流 2

实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流也采用这种模式,这样子有效避免的递归,防止了爆栈么么哒 1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next,anti:point; 6 end; 7 var 8 i,j,k,l,m,n,s,t,flow:longint; 9 a,e:a

【模板】网络最大流

题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数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

网络最大流增广路模板(EK &amp; Dinic)

EK算法: int fir[maxn]; int u[maxm],v[maxm],cap[maxm],flow[maxm],nex[maxm]; int e_max; int p[maxn],q[maxn],d[maxn]; void add_edge(int _u,int _v,int _w) { int e; e=e_max++; u[e]=_u;v[e]=_v;cap[e]=_w; nex[e]=fir[u[e]];fir[u[e]]=e; e=e_max++; u[e]=_v;v[e]=

POJ--1087--A Plug for UNIX【Dinic】网络最大流

链接:http://poj.org/problem?id=1087 题意:提供n种插座,每种插座只有一个,有m个设备需要使用插座,告诉你设备名称以及使用的插座类型,有k种转换器,可以把某种插座类型转为另一种,可以嵌套使用,比如有设备需使用第4种插座,现在只有第一种插座,但是有两个转换器,1→3和3→4,则通过这两个转换器设备可以充电.每种转换器有无数个.现告诉你相应信息,求至少有多少个设备无法使用插座. 网络最大流单源点单汇点,是一道基础题,图建好就能套模板了.关键是图怎么建. 还是自己设一个源