• poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap


    poj 2391 Ombrophobic Bovines,

    最大流, 拆点, 二分


    dinic

    /*
     * Author: yew1eb
     * Created Time:  2014年10月31日 星期五 15时39分22秒
     * File Name: poj2391.cpp
     */
    #include <ctime>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    typedef long long ll;
    const int inf = 1e9;
    const ll  INF = 1e18;
    const double eps = 1e-8;
    const double pi = acos(-1.0);
    const int maxn = 600;
    const int maxm = 100000;
    struct Edge{
    	int to, next;
    	int cap;
    	Edge(){}
    	Edge(int nt, int t, int cp):next(nt),to(t),cap(cp){}
    }edge[maxm];
    
    int head[maxn], tot;
    int n, m, S, T;
    
    void init(){
    	tot = 0;
    	memset(head, -1, sizeof head );
    }
    
    void add(int u, int v, int c){
    	edge[tot] = Edge(head[u], v, c); head[u] = tot++;
    	edge[tot] = Edge(head[v], u, 0); head[v] = tot++;
    }
    
    int d[maxn];
    bool vis[maxn];
    
    bool bfs(){
    	queue<int> q;
    	q.push(S);
    	memset(vis, 0, sizeof vis );
    	vis[S] = 1; d[S] = 0;
    	while(!q.empty()){
    		int u = q.front(); q.pop();
    		for(int i=head[u]; ~i; i=edge[i].next){
    			int &v = edge[i].to;
    			if(!vis[v] && edge[i].cap>0){
    				vis[v] = 1;
    				d[v] = d[u] + 1;
    				q.push(v);
    			}
    		}
    	}
    	return vis[T];
    }
    
    int dfs(int u, int a){
    	if(u==T||a==0) return a;
    	int flow = 0, f;
    	for(int i=head[u];~i; i=edge[i].next){
    		int &v = edge[i].to;
    		if(d[u]+1==d[v]&&(f=dfs(v,min(a,edge[i].cap)))>0){
    			edge[i].cap -= f;
    			edge[i^1].cap += f;
    			flow += f;
    			a -= f;
    			if(a==0) break;
    		}
    	}
    	return flow;
    }
    
    int dinic(){
    	int flow = 0;
    	while(bfs()){
    		flow += dfs(S, inf);
    	}
    	return flow;
    }
    
    ll g[maxn][maxn];
    void floyd(){
    	for(int k=1; k<=n; ++k)
    		for(int i=1; i<=n; ++i)
    			for(int j=1; j<=n; ++j){
    				g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
    			}
    }
    
    int a[maxn], b[maxn];
    void create_graph(ll x){
    	init();
    	for(int i=1; i<=n; ++i)
    		for(int j=1; j<=n; ++j)
    			if(g[i][j]<=x)	add(i,j+n, inf);
    	for(int i=1; i<=n; ++i){
    		add(S, i, a[i]);
    		add(i+n, T, b[i]);
    	}
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
       // freopen("out.cpp", "w", stdout);
    #endif // ONLINE_JUDGE
    	scanf("%d%d", &n, &m);
    	int u, v, c;
    	S = 0, T = 2*n+2;
    	int sum = 0;
    	for(int i=1; i<=n; ++i){
    		scanf("%d%d", &a[i], &b[i]);
    		sum += a[i];
    	}
    	
    	for(int i=1; i<=n; ++i) {
    		g[i][i] = 0;
    		for(int j=i+1; j<=n; ++j) 
    			g[i][j] = g[j][i] = INF;
    	}
    	for(int i=1; i<=m; ++i){
    		scanf("%d%d%d", &u, &v, &c);
    		if(g[u][v]>c) g[u][v] = g[v][u] = c;
    	}
    	floyd();
    		
    	//bsearch
    	ll l = 0, r = 0, mid, ans = -1;
    	for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j)
    		if(g[i][j]<INF) r = max(r, g[i][j]);
    	while(l<=r){
    		mid = (l+r)>>1;
    		create_graph(mid);
    		int flow = dinic();
    		if(flow == sum){
    			ans = mid;
    			r = mid - 1;
    		}else 
    			l = mid + 1;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    



    isap

    int get_flow(int u, int flow)
    {
        if(u==T || flow==0)return flow;
        int res=0, f;
        for(int i=head[u]; ~i; i=edge[i].next) {
            int &v = edge[i].to;
            if(d[u]>d[v] && (f=get_flow(v,min(flow,edge[i].cap)))>0) {
                edge[i].cap -= f;
                edge[i^1].cap += f;
                res += f;
                flow -= f;
                if(flow==0) return res;
            }
        }
        if(!(--gap[d[u]]))d[S]=cnt+2;
        gap[++d[u]]++;
        return res;
    }
    
    int isap()
    {
        int flow = 0;
        memset(gap, 0, sizeof gap );
        memset(d, 0, sizeof d );
        cnt = T-S+1;//顶点数
        gap[0] = cnt;
        while(d[S]<cnt) flow += get_flow(S, inf);
        return flow;
    }
    


  • 相关阅读:
    PHP添加Redis模块及连接
    Redis高级应用
    Redis常用命令
    Redis的数据类型及操作
    Redis下载及安装部署
    NoSQL介绍
    8种Nosql数据库系统对比
    JQ插件
    libcurl一般用法
    密钥对加密原理
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6774652.html
Copyright © 2020-2023  润新知