OIIIIIIII

「LuoguP3376」 【模板】网络最大流

题目描述

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

输入输出格式

输入格式:

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


题解

就是个模板题啊!QAQ

//其实就是挂个板子2333

  1 /*
  2     qwerta
  3     P3376 【模板】网络最大流
  4     Accepted
  5     100
  6     代码 C++,1.68KB
  7     提交时间 2018-07-12 17:31:29
  8     耗时/内存
  9     140ms, 4847KB
 10 */
 11 #include<cmath>
 12 #include<queue>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<iostream>
 16 using namespace std;
 17 struct emm{
 18     int e,f,v;
 19 }a[200007];//邻接链表存边
 20 int h[10007],cur[10007];//cur:当前弧优化(没什么用
 21 int n,m,s,t;
 22 int tot=1;
 23 inline int read()//快读
 24 {
 25     char ch=getchar();
 26     int s=1,x=0;
 27     while(ch<'0'||ch>'9'){if(ch=='-')s=-1;ch=getchar();}
 28     while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
 29     return s*x;
 30 }
 31 inline void con(int l,int r,int w)//加边
 32 {
 33     a[++tot].f=h[l];
 34     h[l]=tot;
 35     //cur[l]=h[l];
 36     a[tot].e=r;
 37     a[tot].v=w;
 38     return;
 39 }
 40 inline void scan()//读入,建图
 41 {
 42     n=read(),m=read(),s=read(),t=read();
 43     for(int i=1;i<=m;++i)
 44     {
 45         int z=read(),y=read(),l=read();
 46         con(z,y,l);
 47         con(y,z,0);
 48     }
 49     return;
 50 }
 51 //Dinic
 52 queue<int>q;//bfs的queue
 53 int  d[100007];//分层图的深度
 54 inline bool bfs()
 55 {
 56     memset(d,0,sizeof(d));//初始化
 57     d[s]=1;//标记源点深度
 58     q.push(s);
 59     for(int i=1;i<=n;++i)cur[i]=h[i];//恢复cur数组
 60     while(!q.empty())
 61     {
 62         int now=q.front();
 63         q.pop();
 64         //扩张
 65         for(int i=h[now];i;i=a[i].f)
 66         if(!d[a[i].e]&&a[i].v)//若未被标记过并且该边在残量网络中
 67         {
 68             d[a[i].e]=d[now]+1;
 69             q.push(a[i].e);
 70         }
 71     }
 72     return d[t];//返回s,t是否联通
 73 }
 74 int dfs(int x,int al)
 75 {
 76     if(x==t||!al)return al;
 77     int tot=0;
 78     for(int i=cur[x];i;i=a[i].f)
 79     {
 80         cur[x]=i;//当前弧优化
 81         if(d[a[i].e]==d[x]+1&&a[i].v)
 82         {
 83             int f=dfs(a[i].e,min(al,a[i].v));//往下找
 84             if(f)//若非0
 85             {
 86                 a[i].v-=f;
 87                 a[i^1].v+=f;
 88                 tot+=f;
 89                 al-=f;
 90                 if(!al)break;
 91             }
 92         }
 93     }
 94     if(!tot)d[x]=-1;//最有用的优化!(敲黑板
 95     return tot;//返回流量值
 96 }
 97 inline void run()//运行
 98 {
 99     long long ans=0;
100     while(bfs())ans+=dfs(s,2147483647);
101     cout<<ans;
102     return;
103 }
104 int main()//超短主函数(当年码风真奇怪orz
105 {
106     scan();
107     run();
108     return 0;
109 }    

 

posted @ 2018-10-03 21:22  qwertaya  阅读(300)  评论(0编辑  收藏  举报
MDZX
Changsha
Fulan