Gym - 101908G Gasoline (二分+网络流)

版权声明:Why is everything so heavy? https://blog.csdn.net/lzc504603913/article/details/83154450

G. Gasoline

time limit per test

0.5 s

memory limit per test

1024 MB

input

standard input

output

standard output

After the end of the truck drivers' strike, you and the rest of Nlogônia logistics specialists now have the task of planning the refueling of the gas stations in the city. For this, we collected information on stocks of RR refineries and about the demands of PP gas stations. In addition, there are contractual restrictions that some refineries cannot supply some gas stations; When a refinery can provide a station, the shorter route to transport fuel from one place to another is known.

The experts' task is to minimize the time all stations are supplied, satisfying their demands. The refineries have a sufficiently large amount of trucks, so that you can assume that each truck will need to make only one trip from a refinery to a gas station. The capacity of each truck is greater than the demand of any gas station, but it may be necessary to use more than one refinery.

Input

The first line of the input contains three integers P,R,CP,R,C, respectively the number of gas stations, the number of refineries and the number of pairs of refineries and gas stations whose time will be given (1≤P,R≤10001≤P,R≤1000; 1≤C≤200001≤C≤20000). The second line contains PP integers DiDi (1≤Di≤1041≤Di≤104), representing the demands in liters of gasoline of the gas stations i=1,2,…,Pi=1,2,…,P, in that order. The third line contains RR integers EiEi (1≤Ei≤1041≤Ei≤104), representing stocks, in liters of gasoline, of refineries i=1,2,…,Ri=1,2,…,R, in that order. Finally, the latest CClines describe course times, in minutes, between stations and refineries. Each of these rows contains three integers, I,J,TI,J,T (1≤I≤P1≤I≤P; 1≤J≤R1≤J≤R; 1≤T≤1061≤T≤106), where II is the ID of a post, JJ is the ID of a refinery and TT is the time in the course of a refinery truck JJ to II. No pair (J,I)(J,I) repeats. Not all pairs are informed; If a pair is not informed, contractual restrictions prevents the refinery from supplying the station.

Output

Print an integer that indicates the minimum time in minutes for all stations to be completely filled up. If this is not possible, print −1.

Examples

input

Copy

3 2 5
20 10 10
30 20
1 1 2
2 1 1
2 2 3
3 1 4
3 2 5

output

Copy

4

input

Copy

3 2 5
20 10 10
25 30
1 1 3
2 1 1
2 2 4
3 1 2
3 2 5

output

Copy

5

input

Copy

4 3 9
10 10 10 20
10 15 30
1 1 1
1 2 1
2 1 3
2 2 2
3 1 10
3 2 10
4 1 1
4 2 2
4 3 30

output

Copy

-1

input

Copy

1 2 2
40
30 10
1 1 100
1 2 200

output

Copy

200

题意:边之间有时间,求把油站填满的最小时间。

解题思路:很容易想到是网络流,关键是最小时间。我们直接二分最小时间,然后如果某条边的时间比二分值小,那么就连边。然后跑最大流,看看最大流等不等于油站和,等于的话证明可行。

#include<iostream>
#include<math.h>
#include<string.h>
#include<queue>
using namespace std;
const int MAXN=4005;
const int INF=0x3f3f3f3f;
typedef long long ll;

int X[MAXN];
int Y[MAXN];

struct edge{
    int u,v,t;
}e1[40001];
int P,R,C;

struct Edge
{
    int v, next;
    ll flow;
} e[50001];

int head[MAXN], edge_num, layer[MAXN];

void addedge(int u, int v, ll w)
{
    e[edge_num].v = v;
    e[edge_num].flow = w;
    e[edge_num].next = head[u];
    head[u] = edge_num++;
    
    e[edge_num].v = u;
    e[edge_num].flow = 0;
    e[edge_num].next = head[v];
    head[v] = edge_num++;
}

bool bfs(int start, int End)
{
    queue<int> Q;
    Q.push(start);
    memset(layer, 0, sizeof(layer));
    layer[start] = 1;
    while (Q.size())
    {
        int u = Q.front();
        Q.pop();
        
        if (u == End)
            return true;
        
        for (int j = head[u]; j != -1; j = e[j].next)
        {
            int v = e[j].v;
            
            if (layer[v] == false && e[j].flow)
            {
                layer[v] = layer[u] + 1;
                Q.push(v);
            }
        }
    }
    
    return false;
}
ll dfs(int u, ll MaxFlow, int End)
{
    if (u == End)
        return MaxFlow;
    
    ll uflow = 0;
    
    for (int j = head[u]; j != -1; j = e[j].next)
    {
        int v = e[j].v;
        
        if (layer[v] - 1 == layer[u] && e[j].flow)
        {
            ll flow = min(MaxFlow - uflow, e[j].flow);
            flow = dfs(v, flow, End);
            
            e[j].flow -= flow;
            e[j ^ 1].flow += flow;
            
            uflow += flow;
            
            if (uflow == MaxFlow)
                break;
        }
    }
    if (uflow == 0)
        layer[u] = 0;
    return uflow;
}
ll dinic(int start, int End)
{
    ll MaxFlow = 0;
    while (bfs(start, End))
        MaxFlow += dfs(start, INF, End);
    return MaxFlow;
}


int cnt=0;
int S,T;
int SX[MAXN];
int SY[MAXN];
ll sum=0;

void rebuild(int m){
    cnt=0;
    memset(head,-1,sizeof(head));
    edge_num=0;
    for(int i=1;i<=R;i++){
        addedge(S,SX[i],X[i]);
    }
    
    for(int j=1;j<=P;j++){
        addedge(SY[j],T,Y[j]);
    }
    
    for(int i=1;i<=C;i++){
        if(e1[i].t<=m){
            addedge(SX[e1[i].v],SY[e1[i].u],INF);
        }
    }
}

bool judge(){
    ll fl=dinic(S,T);
    if(fl<sum){
        return false;
    }
    else
        return true;
}

int main(){
    scanf("%d%d%d",&P,&R,&C);
    for(int i=1;i<=P;i++){
        scanf("%d",&Y[i]);
        sum=sum+ll(Y[i]);
    }
    
    for(int i=1;i<=R;i++)
        scanf("%d",&X[i]);
    
    for(int i=1;i<=C;i++)
        scanf("%d%d%d",&e1[i].u,&e1[i].v,&e1[i].t);
    
    S=++cnt;
    T=++cnt;
    for(int i=1;i<=R;i++)
        SX[i]=++cnt;
    
    for(int j=1;j<=P;j++)
        SY[j]=++cnt;
    
    int L=1,R=1000005;
    
    while(L<R){
        int m=(L+R)/2;
        rebuild(m);
        if(judge()){
            R=m;
        }
        else
            L=m+1;	
    }
    
    if(L==1000005)
        cout<<-1<<endl;
    else
        printf("%d\n",L);
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lzc504603913/article/details/83154450