zoukankan      html  css  js  c++  java
  • bzoj 1412 最小割 网络流

      比较明显的最小割建模, 因为我们需要把狼和羊分开。

      那么我们连接source和每个羊,流量为inf,代表这条边不能成为最小割中的点,同理连接每个狼和汇,流量为inf,正确性同上,那么对于每个相邻的羊和狼,连接边,流量为1,代表隔开这两个点需要1的代价,对于每个空地和狼或者羊,连接边,流量为1,代表隔开这个两个点的代价为1,同时需要注意的是,对于空地之间的连边也应该是1,因为很有可能狼和羊通过空地相遇。这样做最大流就行了。

      反思:手残将空地之间的连成inf了。。。

    /**************************************************************
        Problem: 1412
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:112 ms
        Memory:3152 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        n, m                        :longint;
        num, map                    :array[0..210,0..210] of longint;
        pre, other, len             :array[0..200010] of longint;
        last                        :array[0..20010] of longint;
        l                           :longint;
        source, sink                :longint;
        go                          :array[0..2,0..4] of longint;
        que, d                      :array[0..20010] of longint;
        ans                         :longint;
         
    procedure connect(x,y,z:longint);
    begin
        inc(l);
        pre[l]:=last[x];
        last[x]:=l;
        other[l]:=y;
        len[l]:=z;
    end;
         
    function min(a,b:longint):longint;
    begin
        if a>b then exit(b) else exit(a);
    end;
         
    procedure init;
    var
        i, j, k                     :longint;
        x                           :longint;
        nx, ny                      :longint;
    begin
        go[1,1]:=-1; go[2,2]:=1; go[1,3]:=1; go[2,4]:=-1;
        read(n,m);
        l:=1;
        for i:=1 to n do
            for j:=1 to m do num[i,j]:=(i-1)*m+j;
         
        source:=n*m+2; sink:=source+1;
         
        for i:=1 to n do
            for j:=1 to m do read(map[i,j]);
         
        for i:=1 to n do
            for j:=1 to m do
            begin
                if map[i,j]=1 then
                begin
                    connect(source,num[i,j],maxlongint);
                    connect(num[i,j],source,0);
                end else
                if map[i,j]=2 then
                begin
                    connect(num[i,j],sink,maxlongint);
                    connect(sink,num[i,j],0);
                end;
                for k:=1 to 4 do
                begin
                    nx:=i+go[1,k];
                    ny:=j+go[2,k];
                    if (nx<1) or (nx>n) or (ny<1) or (ny>m) then  continue;
                    if map[i,j]<>map[nx,ny] then
                    begin
                        connect(num[i,j],num[nx,ny],1);
                        connect(num[nx,ny],num[i,j],0);
                    end;
                    if (map[i,j]=map[nx,ny]) and (map[i,j]=0) then
                    begin
                        connect(num[i,j],num[nx,ny],1);
                        connect(num[nx,ny],num[i,j],0);
                    end;
                end;
            end;
    end;
     
    function bfs:boolean;
    var
        q, p                        :longint;
        h, t, cur                   :longint;
    begin
        fillchar(d,sizeof(d),0);
        que[1]:=source;
        d[source]:=1;
        h:=0; t:=1;
        while h<t do
        begin
            inc(h);
            cur:=que[h];
            q:=last[cur];
            while q<>0 do
            begin
                p:=other[q];
                if (len[q]>0) and (d[p]=0) then
                begin
                    inc(t);
                    que[t]:=p;
                    d[p]:=d[cur]+1;
                    if p=sink then exit(true);
                end;
                q:=pre[q];
            end;
        end;
        exit(false);
    end;
     
    function dinic(x,flow:longint):longint;
    var
        q, p                        :longint;
        tmp, rest                   :longint;
    begin
        if x=sink then exit(flow);
        rest:=flow;
        q:=last[x];
        while q<>0 do
        begin
            p:=other[q];
            if (len[q]>0) and (d[p]=d[x]+1) and (rest>0) then
            begin
                tmp:=dinic(p,min(rest,len[q]));
                dec(rest,tmp);
                dec(len[q],tmp);
                inc(len[q xor 1],tmp);
            end;
            q:=pre[q];
        end;
        exit(flow-rest);
    end;
     
    procedure main;
    begin
        while bfs do
            ans:=ans+dinic(source,maxlongint);
        writeln(ans);
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    乌龟git
    CI的model层的操作
    排序算法
    linux安装教程
    linux命令Netstat
    linux压缩和解压缩
    标准库模块time,datetime
    为什么计算机时间和众多编程语言要从1970年1月1日开始算起
    模块和包的导入
    Python封装应用程序的最佳项目结构是什么?
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3523845.html
Copyright © 2011-2022 走看看