标签:text bool while 16px mem 说明 输入输出格式 开始 com
2017-09-17
在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。
农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。
根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。
输入格式:
第1行: 两个用空格分开的整数N (0 <= N <= 200) 和 M (2 <= M <= 200)。N是农夫John已经挖好的排水沟的数量,M是排水沟交叉点的数量。交点1是水潭,交点M是小溪。
第二行到第N+1行: 每行有三个整数,Si, Ei, 和 Ci。Si 和 Ei (1 <= Si, Ei <= M) 指明排水沟两端的交点,雨水从Si 流向Ei。Ci (0 <= Ci <= 10,000,000)是这条排水沟的最大容量。
输出格式:
输出一个整数,即排水的最大流量。
5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10
50
题目翻译来自NOCOW。
USACO Training Section 4.2
找流量我很绝望啊,ID编号我从0开始的哇wa哇wa的.kmp半天题解我很绝望啊
因为2^1=3;3^1=2<<<<笑(:
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<queue> #define ll int using namespace std; const ll maxn=100000+99999; const ll INT=1e9+7; ll read(){ ll an=0,f=1; char ch=getchar(); while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘);ch=getchar();} while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();} return an*f; } ll dis[maxn],n,m,cnt=1,f[maxn]; ll ans,S,F; struct saber{ ll nex,to,wi; }b[(maxn<<1)+999]; queue<ll>q; bool bfs(){ memset(dis,-1,sizeof(dis)); while( !q.empty() )q.pop( ); q.push(S); dis[S]=0; while(!q.empty()){ ll x=q.front(); q.pop(); for(ll i=f[x];i;i=b[i].nex){ int v=b[i].to; if(dis[v]==-1&&b[i].wi>0){ dis[v]=dis[x]+1; if(v==F)return 1; q.push(v); } } } return 0; } ll dfs(ll x,ll val){ ll i,u,add=0; if(x==F){return val;} for(ll i=f[x];i;i=b[i].nex){ int v=b[i].to; if(dis[v]==dis[x]+1&&b[i].wi>0&&( add=(dfs(v,min(val,b[i].wi) ) ) ) ){ b[i].wi-=add; b[i^1].wi+=add; return add; } } return 0; } void add(ll x,ll y,ll z){ cnt++; b[cnt].nex=f[x]; f[x]=cnt; b[cnt].to=y; b[cnt].wi=z; } void Dinic(){ while(bfs()){ ans+=dfs(S,INT); } } int main(){ n=read();m=read(); S=read();F=read(); for(ll i=1;i<=m;i++){ ll x=read(),y=read(),z=read(); add(x,y,z); add(y,x,0); } Dinic(); cout<<ans; return 0; }
by:s_a_b_e_r
裸的网络最大流板子题啊
写的dinic
安利一个学dinic的博客,写的非常好?
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=209; int n,m,cnt=1,p[N],dis[N],ans; queue<int>q; struct edge{int to,nex,val;}e[N<<1]; void add(int u,int v,int w) { ++cnt; e[cnt]=(edge){v,p[u],w}; p[u]=cnt; } bool bfs() { memset(dis,-1,sizeof(dis)); while(!q.empty())q.pop(); q.push(1);dis[1]=0; while(!q.empty()) { int u=q.front();q.pop(); for(int i=p[u];i;i=e[i].nex) { int v=e[i].to; if(dis[v]==-1&&e[i].val) { dis[v]=dis[u]+1; if(v==n)return 1; q.push(v); } } } return 0; } int dfs(int u,int maxx) { if(u==n)return maxx; int used=maxx; for(int i=p[u];i;i=e[i].nex) { int v=e[i].to; if(dis[u]+1==dis[v]&&used&&e[i].val) { int re=dfs(v,min(used,e[i].val)); if(!re)dis[v]=-1; used-=re; e[i].val-=re; e[i^1].val+=re; } } return maxx-used; } void dinic() { while(bfs())ans+=dfs(1,int(1e9)); } int main() { scanf("%d%d",&m,&n); for(int i=1;i<=m;++i) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z);add(y,x,0); } dinic(); cout<<ans; return 0; }
by:wypx
luogu P2740 [USACO4.2]草地排水Drainage Ditches
标签:text bool while 16px mem 说明 输入输出格式 开始 com
原文地址:http://www.cnblogs.com/ck666/p/7532923.html