zoukankan      html  css  js  c++  java
  • P2740 [USACO4.2]草地排水Drainage Ditches(dinic)

    Aimee

    显然这是一个网络流

    一开始,我们大可以随便找一条可行流

    然后再找一条,可是如果要返回怎么办?可以建立对应的反向边,反向边的容量即即为正向边流量,构成残余网络,在残余网络上找到的从s( ightarrow)t的路径,就是一条可行流,并且,找到最大流的充要条件是它的对应残余网络没有增广路

    这就是FF #方法

    那么怎么求呢,一下给出了dinic做法

    把残余网络用bfs序搞成分层图

    就是每一次在对应的残余网络上找不止一条增广路,对于每一个点,把尽可能多的流量分给子节点,之后后退,执行相同操作,最后更新残余网络,直到找不到增广路

    方案数?

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    int n,m,s,t;
    int p;
    int x,y,z;
    int head[205];
    long long Aimee;
    queue<int> q;
    struct e{
    	int to;
    	long long v;
    	int ne;
    } ed[200001];
    void add(int f,int t,int v){
    	ed[++p].ne=head[f];ed[p].to=t;ed[p].v=v;head[f]=p;
    	ed[++p].ne=head[t];ed[p].to=f;ed[p].v=0;head[t]=p;
    }
    int vis[200001];
    long long exf[200001];
    int pre[200001];
    int le[200001];
    int fr[200001];
    const long long inf= (1<<30);
    bool bfs(){
    	memset(le,-1,sizeof(le));
    	while(!q.empty()){
    		q.pop();
    	}
    	q.push(s);
    	le[s]=0;
    	fr[s]=head[s];
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=head[u];i;i=ed[i].ne){
    			int v=ed[i].to;
    			if(ed[i].v&&le[v]==-1){
    				q.push(v);le[v]=le[u]+1;
    				fr[v]=head[v];
    				if(v==t) return 1;
    			}
    		}
    	}
    	return 0;
    }
    long long dfs(int  now,int tas){
    	if(now==t) return tas;
    	long long znx=0;
    	for(int i=fr[now];i&&znx<tas;i=ed[i].ne){
    		fr[now]=i;
    		int v=ed[i].to;
    		if(ed[i].v&&le[v]==le[now]+1){
    			long long  jdn=dfs(v,min(tas-znx,ed[i].v));
    			if(!jdn) le[v]=-1;
    			ed[i].v-=jdn;
    			ed[i^1].v+=jdn;
    			znx+=jdn;
    		}
    	}
    	return znx;
    }
    long long znx;
    long long dinic(){
    	while(bfs()){
    		while(znx=dfs(s,inf)){
    			Aimee+=znx;
    		}
    	}
    	return Aimee;
    }
    int main(){
    	scanf("%d%d",&m,&n);
    	s=1;
    	t=n;
    	p=1;
    	for(int i=1;i<=m;++i){
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    	}
    	cout<<dinic();
    	//printf("%lld",Aimee);
    	return 0;
    }
    
  • 相关阅读:
    【转】CUDA5/CentOS6.4
    【转】centos 6.4 samba 安装配置
    【转】Install MATLAB 2013a on CentOS 6.4 x64 with mode silent
    【转】Getting xrdp to work on CentOS 6.4
    【VLFeat】使用matlab版本计算HOG
    Unofficial Windows Binaries for Python Extension Packages
    March 06th, 2018 Week 10th Tuesday
    March 05th, 2018 Week 10th Monday
    March 04th, 2018 Week 10th Sunday
    March 03rd, 2018 Week 9th Saturday
  • 原文地址:https://www.cnblogs.com/For-Miku/p/14371698.html
Copyright © 2011-2022 走看看