• Gym


    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 (1P,R10001≤P,R≤1000; 1C200001≤C≤20000). The second line contains PP integers DiDi (1Di1041≤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 (1Ei1041≤Ei≤104), representing stocks, in liters of gasoline, of refineries i=1,2,,Ri=1,2,…,R, in that order. Finally, the latest CC lines describe course times, in minutes, between stations and refineries. Each of these rows contains three integers, I,J,TI,J,T (1IP1≤I≤P; 1JR1≤J≤R; 1T1061≤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
    3 2 5
    20 10 10
    30 20
    1 1 2
    2 1 1
    2 2 3
    3 1 4
    3 2 5
    Output
    4
    Input
    3 2 5
    20 10 10
    25 30
    1 1 3
    2 1 1
    2 2 4
    3 1 2
    3 2 5
    Output
    5
    Input
    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
    -1
    Input
    1 2 2
    40
    30 10
    1 1 100
    1 2 200
    Output
    200

    二分花费时间跑最大流。

    #include <bits/stdc++.h>
    using namespace std;
    int P,R,C;
    int p[1005],r[1005];
    struct E
    {
        int u,v,w;
    } e[20005];
    int sum;
    const int MAXN = 100010;
    const int MAXM = 400010;
    const int INF = 0x3f3f3f3f;
    struct Edge
    {
        int to,next,cap,flow;
    } edge[MAXM];
    int tol;
    int head[MAXN];
    int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
    void init()
    {
        tol = 0;
        memset(head, -1,sizeof(head));
    }
    
    void addedge(int u,int v,int w,int rw=0)
    {
        edge[tol].to = v;
        edge[tol].cap = w;
        edge[tol].next = head[u];
        edge[tol].flow = 0;
        head[u] = tol++;
        edge[tol].to = u;
        edge[tol].cap = rw;
        edge[tol].next = head[v];
        edge[tol].flow = 0;
        head[v]=tol++;
    }
    
    int sap(int start,int end,int N)
    {
        memset(gap,0,sizeof(gap));
        memset(dep,0,sizeof(dep));
        memcpy(cur,head,sizeof(head));
        int u = start;
        pre[u] = -1;
        gap[0] = N;
        int ans = 0;
        while(dep[start] < N)
        {
            if(u == end)
            {
                int Min = INF;
                for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
                    if(Min > edge[i].cap -edge[i].flow)
                        Min = edge[i].cap -edge[i].flow;
                for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
                {
                    edge[i].flow += Min;
                    edge[i^1].flow -= Min;
                }
                u = start;
                ans += Min;
                continue;
            }
            bool flag = false;
            int v;
            for(int i = cur[u]; i != -1; i = edge[i].next)
            {
                v = edge[i].to;
                if(edge[i].cap -edge[i].flow && dep[v]+1 == dep[u])
                {
                    flag = true;
                    cur[u] = pre[v] = i;
                    break;
                }
            }
            if(flag)
            {
                u = v;
                continue;
            }
            int Min = N;
            for(int i = head[u]; i != -1; i = edge[i].next)
                if(edge[i].cap -edge[i].flow && dep[edge[i].to] < Min)
                {
                    Min = dep[edge[i].to];
                    cur[u] = i;
                }
            gap[dep[u]]--;
            if(!gap[dep[u]])
                return ans;
            dep[u] = Min+1;
            gap[dep[u]]++;
            if(u != start)
                u = edge[pre[u]^1].to;
        }
        return ans;
    }
    
    bool judge(int T){
        init();
        for (int i = 1;i <= P;++i){
            addedge(2*i-1,2*i,p[i]);
            addedge(2*i,2*P+2*R+1,INF);
        }
        for (int i = 1;i <= C;++i){
            if (e[i].w <= T) {
                addedge(2*P+2*e[i].u,2*e[i].v-1,r[e[i].u]);
            }
        }
        for (int i = 1;i <= R;++i){
            addedge(0,2*P+2*i-1,INF);
            addedge(2*P+2*i-1,2*P+2*i,r[i]);
        }
        if (sap(0,2*P+2*R+1,2*P+2*R+2) == sum) return true;
            else return false;
    }
    
    
    int main(){
        sum = 0;
        scanf("%d%d%d",&P,&R,&C);
        for (int i = 1;i <= P;++i) scanf("%d",p+i),sum+=p[i];
        for (int i = 1;i <= R;++i) scanf("%d",r+i);
        for (int i = 1;i <= C;++i){
            scanf("%d%d%d",&e[i].v,&e[i].u,&e[i].w);
        }
        int l = 1,r = 1000005;
        bool flag = false;
    
        while(l < r){
            int mid = (l + r)/2;
            if (judge(mid)){
                r = mid;
                flag = true;
            }else{
                l = mid+1;
            }
        }
        if (flag) printf("%d
    ",l);else puts("-1");
    }
  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/mizersy/p/9737788.html
Copyright © 2020-2023  润新知