zoukankan      html  css  js  c++  java
  • bzoj 3171 费用流

    每个格拆成两个点,出点连能到的点的入点,如果是箭头指向

    方向费用就是0,要不就是1,源点连所有出点,所有入点连

    汇点,然后费用流

    /**************************************************************
        Problem: 3171
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:32 ms
        Memory:1180 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        n, m                        :longint;
        map                         :array[0..30,0..30] of longint;
        pre, other, len, cost       :array[0..50010] of longint;
        last                        :array[0..10000] of longint;
        l                           :longint;
        num                         :array[0..30,0..30] of longint;
        go                          :array[0..2,0..4] of longint;
        source, sink                :longint;
        ans                         :longint;
        que, dis, father            :array[0..10000] of longint;
        flag                        :array[0..10000] 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;
        c                           :char;
        curx, cury                  :longint;
         
    begin
        readln(n,m);
        go[1,1]:=-1; go[2,2]:=1;
        go[1,3]:=1; go[2,4]:=-1;
        l:=1;
        for i:=1 to n do
        begin
            for j:=1 to m do
            begin
                read(c);
                if c='U' then map[i,j]:=1 else
                if c='R' then map[i,j]:=2 else
                if c='D' then map[i,j]:=3 else
                if c='L' then map[i,j]:=4;
            end;
            readln;
        end;
        for i:=1 to n do
            for j:=1 to m do num[i,j]:=((i-1)*m+j);
        source:=2*m*n+2; sink:=source+1;
        for i:=1 to n do
            for j:=1 to m do
                for k:=1 to 4 do
                begin
                    curx:=i+go[1,k];
                    cury:=j+go[2,k];
                    if curx=0 then curx:=n; if curx=n+1 then curx:=1;
                    if cury=0 then cury:=m; if cury=m+1 then cury:=1;
                    if map[i,j]=k then
                    begin
                        connect(num[i,j]+n*m,num[curx,cury],1,0);
                        connect(num[curx,cury],num[i,j]+n*m,0,0);
                    end else
                    begin
                        connect(num[i,j]+n*m,num[curx,cury],1,1);
                        connect(num[curx,cury],num[i,j]+n*m,0,-1);
                    end;
                end;
        for i:=1 to n do
            for j:=1 to m do
            begin
                connect(source,num[i,j]+n*m,1,0);
                connect(num[i,j]+n*m,source,0,0);
                connect(num[i,j],sink,1,0);
                connect(sink,num[i,j],0,0);
            end;
        {for i:=1 to n do 
            for j:=1 to m do 
            begin
                connect(num[i,j],num[i,j]+n*m,1,0);
                connect(num[i,j]+n*m,num[i,j],0,0);
            end;}
    end;
     
    function spfa:boolean;
    var
        q, p, cur                   :longint;
        h, t                        :longint;
    begin
        filldword(dis,sizeof(dis) div 4,maxlongint div 10);
        h:=0; t:=1;
        que[1]:=source; dis[source]:=0;
        while h<>t do
        begin
            h:=h mod 10000+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
                        dis[p]:=dis[cur]+cost[q];
                        father[p]:=q;
                        if not flag[p] then
                        begin
                            t:=t mod 10000+1;
                            que[t]:=p;
                            flag[p]:=true;
                        end;
                    end;
                end;
                q:=pre[q];
            end;
        end;
        if dis[sink]=maxlongint div 10 then exit(false) else exit(true);
    end;
     
    procedure update;
    var
        cur, low                    :longint;
    begin
        cur:=sink;
        low:=maxlongint;
        while cur<>source do
        begin
            low:=min(low,len[father[cur]]);
            cur:=other[father[cur] xor 1];
        end;
        cur:=sink;
        while cur<>source do
        begin
            dec(len[father[cur]],low);
            inc(len[father[cur] xor 1],low);
            inc(ans,low*cost[father[cur]]);
            cur:=other[father[cur] xor 1];
        end;
    end;
     
    procedure main;
    begin
        while spfa do
            update;
        writeln(ans);
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    翻译MDN里js的一些方法属性
    ajax相关
    我的面试错题
    写代码通用思路
    工厂模式
    cookie & session
    X-UA-Compatible设置IE浏览器兼容模式
    [转]IE6/IE7/IE8/IE9中tbody的innerHTML不能赋值的完美解决方案
    EasyUseCase 一款脑图转化 Excel 测试用例工具 (1.2 版本升级)
    XMind2TestCase:一个高效测试用例设计的解决方案!
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3492967.html
Copyright © 2011-2022 走看看