POJ-3228: Gold Transportation network flow + two points

analysis

Find the minimum value of the maximum value, so it should be done by dichotomy.
We can establish a source point and a sink point. The flow from the source to each point is the amount of gold at each point, and the flow from each point to the sink is The amount of gold storage at each point, and then the dichotomy distance is used to build a map to determine whether the flow of the sink is equal to the flow of the source

Code


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 220,M = N * N * 2;

int h[N],ne[M],e[M],f[M],idx;
int n,m,S,T,a[N],b[N];
int w[N][N];
int sum;
int q[N],d[N],cur[N];

void add(int x,int y,int z){
    
    
    e[idx] = y,ne[idx] = h[x],f[idx] = z,h[x] = idx++;
    e[idx] = x,ne[idx] = h[y],f[idx] = 0,h[y] = idx++;
}

void init(){
    
    
	memset(w,0x3f,sizeof w);
	sum = 0;
}

bool bfs(){
    
    
    int hh = 0, tt = 0;
    memset(d,-1,sizeof d);
    q[0] = S, d[S] = 0, cur[S] = h[S];
    while(hh <= tt){
    
    
        int t = q[hh ++ ];
        for(int i = h[t];~i;i = ne[i]){
    
    
            int j = e[i];
            if(d[j] == -1 && f[i]){
    
    
                d[j] = d[t] + 1;
                cur[j] = h[j];
                if(j == T) return true;
                q[ ++ tt] = j;
            }
        }
    }
    return false;
}

int find(int u,int limit){
    
    
    if(u == T) return limit;
    int flow = 0;
    for(int i = cur[u];~i && flow < limit;i = ne[i]){
    
    
        cur[u] = i;
        int j = e[i];
        if(d[j] == d[u] + 1 && f[i]){
    
    
            int t = find(j,min(f[i],limit - flow));
            if(!t) d[j] = -1;
            f[i] -= t,f[i ^ 1] +=t,flow += t;
        }
    }
    return flow;
}

int dinic(){
    
    
    int res = 0,flow;
    while(bfs()) while(flow = find(S,INF)) res += flow;
    return res;
}

bool check(int mid){
    
    
	memset(h,-1,sizeof h);
	idx = 0;
	for(int i = 1;i <= n;i++) add(S,i,a[i]),add(i,T,b[i]);
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= n;j++)
			if(w[i][j] <= mid)
				add(i,j,INF);
	return dinic() == sum;
}

int main(){
    
    
	while(scanf("%d",&n) && n){
    
    
		init();
	    for(int i = 1;i <= n;i++) scanf("%d",&a[i]),sum += a[i];
	    for(int i = 1;i <= n;i++) scanf("%d",&b[i]);
	    scanf("%d",&m);
	    for(int i = 1;i <= m;i++) {
    
    
	    	int x,y,z;
	    	scanf("%d%d%d",&x,&y,&z);
	    	w[x][y] = min(w[x][y],z);
	    	w[y][x] = w[x][y];
	    }
	    int l = 0,r = 100000;
		S = 0,T = n + 1;
		bool flag = 0;
		while(l < r){
    
    
			int mid = l + r >> 1;
			if(check(mid)) r = mid,flag = 1;
			else l = mid + 1;
		}
		if(!flag) puts("No Solution");
		else printf("%d\n",l);
	}
	return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/



Guess you like

Origin blog.csdn.net/tlyzxc/article/details/114983506