• bzoj 1070 修车 费用流


     对于这道题,我们看数据范围应该是费用流(起码我的第一反应是。。。)

    然后仔细想想发现可做,那么就开始构图

    对于第I个修理工,我们可以让他修好多辆车,那么假设一个人修了J辆车,

    在他修他修的第K辆车的时候,会让后面的j-k辆车的每个人多等他修k车的时间

    那么我们设每个人一共修了n辆车,他倒数第j个修的车的代价就是j*time(修这辆车的代价)

    那么我们就对于每个人拆点,拆成N个点,代表他倒数第J个修的哪个车,然后求最小费用最大流就行了

    数据范围开始看成60,60了,数组开的不合适,后来懒得改了。。。。

    /**************************************************************
        Problem: 1070
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:556 ms
        Memory:8532 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        n, m                    :longint;
        time                    :array[0..100,0..100] of longint;
        pre, other, len, cost   :array[0..500000] of longint;
        l                       :longint;
        last                    :array[-10..5000] of longint;
        tot                     :longint;
        st, fin                 :longint;   
        que                     :array[0..100000] of longint;
        dis, father             :array[-10..5000] of longint;
        ans                     :longint;
        flag                    :array[-10..5000] of boolean;
         
    function min(a,b:longint):longint;
    begin
        if a>b then min:=b else min:=a;
    end;
         
    procedure connect(a,b,c,d:longint);
    begin
        inc(l);
        pre[l]:=last[a];
        last[a]:=l;
        other[l]:=b;
        len[l]:=c;
        cost[l]:=d;
    end;
         
    procedure init;
    var
        i, j, k                 :longint;
     
    begin
        read(n,m); l:=1;
        for i:=1 to m do
            for j:=1 to n do read(time[j,i]);
         
        st:=-1; fin:=-2;
        tot:=m;
        for i:=1 to m do
        begin
            connect(i,fin,1,0);
            connect(fin,i,0,0);
        end;
        for i:=1 to n do
            for j:=1 to m do
            begin
                inc(tot);
                for k:=1 to m do
                begin
                    connect(tot,k,1,j*time[i,k]);
                    connect(k,tot,0,-j*time[i,k]);
                end;
            end;
        for i:=m+1 to tot do
        begin
            connect(st,i,1,0);
            connect(i,st,0,0);
        end;
    end;
     
    procedure spfa;
    var
        q, p, cur               :longint;
        h, t                    :longint;
    begin
        filldword(dis,sizeof(dis) div 4,maxlongint div 10);
        que[1]:=st;
        dis[st]:=0;
        h:=0; t:=1;
        while t<>h do
        begin
            h:=h mod 100000+1;
            cur:=que[h];
            flag[cur]:=false;
            q:=last[cur];
            while q<>0 do
            begin
                p:=other[q];
                if len[q]>0 then
                begin
                    if dis[p]>dis[cur]+cost[q] then
                    begin
                        father[p]:=q;
                        dis[p]:=dis[cur]+cost[q];
                        if not flag[p] then
                        begin
                            t:=t mod 100000+1;
                            que[t]:=p;
                            flag[p]:=true;
                        end;
                    end;
                end;
                q:=pre[q];
            end;
        end;
    end;
     
    procedure update;
    var
        cur                     :longint;
        low                     :longint;
     
    begin
        low:=maxlongint div 10;
        cur:=fin;
        while cur<>st do
        begin
            low:=min(low,len[father[cur]]);
            inc(ans,cost[father[cur]]);
            cur:=other[father[cur] xor 1];
        end;
        cur:=fin;
        while cur<>st do
        begin
            dec(len[father[cur]],low);
            inc(len[father[cur] xor 1],low);
            cur:=other[father[cur] xor 1]; 
        end;
    end;
     
    procedure main;
    begin
        ans:=0;
        while true do
        begin
            spfa;
            if dis[fin]=maxlongint div 10 then break;
            update;
        end;
        writeln(ans/m:0:2);
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    大学阶段最后的交流
    JavaScript的一些基础性知识
    CSS的一些总结
    JavaWeb的一些理解
    Java Web之XML基础
    Java基础增强
    反射的理解
    Java网络编程
    Java 中剩下的流以及线程方面的知识
    Java中的流操作
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3456539.html
Copyright © 2020-2023  润新知