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;
    }
    
  • 相关阅读:
    ORACLE 查看进程数,已执行任务数, 剩余任务数,删除指定任务
    ORACLE 收集统计整个用户数据
    解决Hystrix dashboard Turbine 一直 Loading…… 及其他坑
    利用 Maven 构造 Spring Cloud 微服务架构 模块使用 spring Boot构建
    AES加解密
    JAVA POI XSSFWorkbook导出扩展名为xlsx的Excel,附带weblogic 项目导出Excel文件错误的解决方案
    JAVA 文件的上传下载
    shell启停服务脚本模板
    JAVA 设计模式之 原型模式详解
    JAVA 设计模式之 工厂模式详解
  • 原文地址:https://www.cnblogs.com/For-Miku/p/14371698.html
Copyright © 2011-2022 走看看