额,题目是英文的,大意如下:
现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条水渠,给出这n条水渠所连接的点和所能流过的最大流量,
求从源点到汇点能流过的最大流量。
题解:很裸是吧,直接上网络流即可,但我加了优化之后只跑了0ms,额,其实就是模板联系
注意:我wa了几次,网上说的重边在dinic中没有必要注意,模板的优越性啊!!!但有一点要注意的是题目翻译太tm坑爹了,多组数据啊!!!我一直以为是一组,尴尬
我的代码和昨天贴的模板不太一样,主要是数据的存储方式不一样,怕考试卡vector,再说了多会一种万一就用上了呢
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <float.h>
using namespace std;
const int maxn=1000005;
int s,t;
int i,n,m,u,c,v,len;
int head[maxn];
int cur[maxn];
int vis[maxn];
int dis[maxn];
const int oo=1000000005;
struct edge{
int u,v,c,f,next;
edge(){u=v=c=f=0;next=-1;}
edge(int x,int y,int z,int w){
u=x;v=y;c=z;f=w;
next=-1;
}
} e[2*maxn];
void add(int u,int v,int c,int f){
len++;
e[len]=edge(u,v,c,f);
e[len].next=head[u];
head[u]=len;
}
int bfs(){
int x;
for(i=1;i<=n+2;i++)
vis[i]=0;
queue <int> q;
q.push(s);
dis[s]=0;
vis[s]=1;
while(!q.empty()){
x=q.front();
for(i=head[x];i!=-1;i=e[i].next){
if(!vis[e[i].v]&&e[i].c>e[i].f){
dis[e[i].v]=dis[x]+1;
q.push(e[i].v);
vis[e[i].v]=1;
}
}
q.pop();
}
return vis[t];
}
int dfs(int x,int a){
if(x==t||a==0)
return a;
int flow=0,f;
int &i=cur[x];
for(i=head[x];i!=-1;i=e[i].next){
if((dis[e[i].v]==dis[x]+1)&&
(f=dfs(e[i].v,min(a,e[i].c-e[i].f)))){
e[i].f+=f;
e[i^1].f-=f;
a-=f;
flow+=f;
if(a==0)
break;
}
}
return flow;
}
int dinic(int s1,int t1){
s=s1;
t=t1;
int flow=0;
while(bfs()){
for(i=1;i<=n+2;i++)
cur[i]=0;
flow+=dfs(s,oo);
}
return flow;
}
int main(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
while(scanf("%d %d",&m,&n)!=EOF){
len=-1;
for(i=1;i<=n+2;i++)
head[i]=-1;
for(i=1;i<=m;i++){
scanf("%d %d %d",&u,&v,&c);
add(u,v,c,0);
add(v,u,0,0);
}
add(n+1,1,oo,0);
add(1,n+1,0,0);
add(n,n+2,oo,0);
add(n+2,n,0,0);
printf("%d\n",dinic(n+1,n+2));
}
return 0;
}