P2402 cow hide network flow

  

Topic background

This is a very simple question, but the cows have been very confusing because of the rain, unable to complete this calculation, so this task is given to you. (The reason cows chaotic look at the subject description)

Title Description

N-block on a farm field. One afternoon, a group of cattle grazing in the field, they are scattered in many fields farm, farm road connected undirected m strips of different path lengths.

Suddenly, heavy rain, cows very confusing, I want to quickly go to the shelter. Each field known to have established a bullpen, but each cow can only accommodate a certain number of cattle shelter, if more than this number, how much a cow can only go to other fields shelter. The cows spend every movement distance 1 1 time, the cows want to know all of them hid in the bullpen, requires a minimum amount of time. (Ie how long it takes a minimum of the last cow to hide in the bullpen).

Input and output formats

Input formats:

 

The first line of the input two integers N, M. N represents the number of field plots, M is the number of paths.

Next N lines of two integers S, P, respectively, the field now has several cows and cow number field of cattle can hold up.

Next M rows, each row of three integers A, B, C, indicating the presence of a connection path A, B, and its length is C.

 

Output formats:

 

An integer that represents all the cows are all hid in the minimum time the bullpen used. If you can not make all the cows have to hide in the bullpen, output -1.

 

Sample input and output

Input Sample # 1:  Copy
3 4 
7 2 
0 4 
2 6 
1 2 40 
3 2 70 
2 3 90 
1 3 120
Output Sample # 1:  Copy
110

Explanation

Sample [explain]

Bullocks 1 1 point directly to cow hide, the remaining five, four points around 2, as well as a 1-> 2-> 3,3 Number 2 Bovine points are also direct hide in, so the slowest time cattle spend is 110.

Data range: 100% of the data, N <= 200 M <= 1500

 

It looked like the sum of network flow but is not seeking time  

Positive Solutions: plus half run to determine whether the maximum flow stream is full

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=1e6;
const int M=4e6+54;

struct edge {
    int to, next, w;
} e[M << 1];
int head[N], cnt = 1;
void add(int x, int y, int z) {
    e[++cnt] = (edge){y, head[x], z};
    head[x] = cnt;
    e[++cnt] = (edge){x, head[y], 0};
    head[y] = cnt;
}
int level[N];
bool bfs(int s, int t) {
    memset(level, 0, sizeof level);
    queue<int> q;
    level[s] = 1;
    q.push(s);
    while (!q.empty()) {
        int pos = q.front();
        q.pop();
        for (int i = head[pos]; i; i = e[i].next) {
            int nx = e[i].to;
            if (!e[i].w || level[nx]) continue;
            level[nx] = level[pos] + 1;
            q.push(nx);
        }
    }
    return level[t];
}
int dfs(int s, int t, int flow) {
    if (s == t) return flow;
    int ret = 0;
    for (int i = head[s]; flow && i; i = e[i].next) {
        int nx = e[i].to;
        if (level[nx] == level[s] + 1 && e[i].w) {
            int tmp = dfs(nx, t, min(flow, e[i].w));
            e[i].w -= tmp;
            e[i ^ 1].w += tmp;
            flow -= tmp;
            ret += tmp;
        }
    }
    if (!ret) level[s] = 0;
    return ret;
}
int dinic(int s, int t) {
    int ret = 0;
    while (bfs(s, t)) ret += dfs(s, t, inf);
    return ret;
}
int n,m,s,t,a,b,c,r,ans,l,dis[300][300],cownum,cow[N],home[N];

bool build(int x)
{
    CLR(head,0);cnt=1;
    s=n*3+1;t=s+1;

    rep(i,1,n)
    add(s,i,cow[i]),add(i+n,t,home[i]);

    rep(i,1,n)
    rep(j,i+1,n)
    {
        if(dis[i][j]<=x)
        add(i,j+n,inf),add(j,i+n,inf);
    }
    return dinic(s,t)==cownum;
}

int main()
{
    RII(n,m);
    rep(i,1,n)RII(cow[i],home[i]),cownum+=cow[i];

    rep(i,1,n)rep(j,i,n)
    if(i!=j)dis[i][j]=dis[j][i]=inf;
    else dis[i][j]=0;
    l=0,r=0;
    rep(i,1,m)
    {
        int u,v,w;RIII(u,v,w);
        dis[u][v]=dis[v][u]=min(dis[v][u],w);
    }
    rep(i,1,n)
    rep(j,1,n)
    rep(k,1,n)
    dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]),r=max(r,dis[i][j]);

    int ans=inf;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if(build(m))r=m-1,ans=min(ans,m);
        else l=m+1;
    }
    cout<<ans;
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11233864.html