[USACO4.2] 草地排水 Drainage Ditches题解
题目背景
在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。
题目描述
FJ 知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。
根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。
输入格式
第一行:两个用空格分开的整数 N(0≤N≤200)和 M(2≤M≤200)。N 是 FJ 已经挖好的排水沟的数量,M 是排水沟交叉点的数量。交点 1 是水潭,交点 M 是小溪。
第二行到第 N+1 行:每行有三个整数 Si,Ei,Ci。Si 和 Ei(1≤Si,Ei≤M)指明排水沟两端的交点,雨水从 Si 流向 Ei。Ci(0≤Ci≤107)是这条排水沟的最大容量。
输出格式
输出一个整数,即排水的最大流量。
输入输出样例
输入 #1复制
5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10
输出 #1复制
50
说明/提示
题目翻译来自 NOCOW。
USACO Training Section 4.2
【数据范围】
对于 100% 的数据,0≤N,M≤200,0≤Ci≤107。
思路
类似模板题,直接改模板题代码。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,m,s,t,u,vv,w,he[500005],d[500005],no[500005],lk=0,cd=0,lof=1e18+7;
struct one{
long long a,b;
long long c,x;
}e[500005];
long long db=1;
vector<long long> v[2005];
queue<one> q;
void ad(long long u1,long long v1,long long w1){
e[++db].a=u1;
e[db].b=v1;
e[db].c=w1;
e[db].x=he[u1];
he[u1]=db;
e[++db].a=v1;
e[db].b=u1;
e[db].c=0;
e[db].x=he[v1];
he[v1]=db;
}
long long abcb(){
for(int i=1;i<=n;i++){
d[i]=lof;
}
queue<long long> q;
q.push(s);
d[s]=0;
no[s]=he[s];
while(q.size()!=0){
long long a1=q.front();
q.pop();
for(int i=he[a1];i!=0;i=e[i].x){
long long tt=e[i].b;
if(e[i].c>=1&&d[tt]==lof){
q.push(tt);
no[tt]=he[tt];
d[tt]=d[a1]+1;
if(tt==t){
return 1;
}
}
}
}
return 0;
}
long long abcd(long long a1,long long b1){
if(a1==t){
return b1;
}
long long df,kl=0;
for(int i=no[a1];i!=0&&b1!=0;i=e[i].x){
no[a1]=i;
long long tt=e[i].b;
if(e[i].c>=1&&d[tt]==d[a1]+1){
df=abcd(tt,min(b1,e[i].c));
if(df==0){
d[tt]=lof;
}
e[i].c-=df;
e[i^1].c+=df;
kl+=df;
b1-=df;
}
}
return kl;
}
int main(){
cin>>m>>n;
s=1;
t=n;
for(int i=1;i<=m;i++){
cin>>u>>vv>>w;
ad(u,vv,w);
}
while(abcb()!=0){
lk+=abcd(s,lof);
}
cout<<lk<<endl;
return 0;
}

浙公网安备 33010602011771号