zoukankan      html  css  js  c++  java
  • bzoj 3232 01分数规划+最大权封闭子图判定

    我们的目标是使v/c最小化,所以构造函数g(x)=v-x*c,那么

    二分一个X,判断当时的v-x*c的值是多少,然后根据g(x)函数的

    单调递减性来二分,判断,直到g(x)=0的时候当前的X就是答案。

    然后我直接写的tle了,这是这两天tle的第3道题了。。。再改改。。。

    /**************************************************************
        Problem: 3232
        User: BLADEVIL
        Language: Pascal
        Result: Time_Limit_Exceed
    ****************************************************************/
     
    //By BLADEVIL
    const
        lim                         =1e-5;
         
    var
        n, m                        :longint;
        pre, other                  :array[0..100010] of longint;
        len                         :array[0..100010] of extended;
        last                        :array[0..3010] of longint;
        tot                         :longint;
        num                         :array[0..60,0..60] of longint;
        key, heng, shu              :array[0..60,0..60] of longint;
        sum                         :longint;
        print                       :extended;
        que, d                      :array[0..3010] of longint;
        source, sink                :longint;
         
    function min(a,b:extended):extended;
    begin
        if a>b then min:=b else min:=a;
    end;
     
    function judge(x:extended):extended;
    begin
        if abs(x)<lim then exit(0);
        if x<0 then exit(-1) else exit(1);
    end;
         
    procedure connect(x,y:longint;z:extended);
    begin
        inc(tot);
        pre[tot]:=last[x];
        last[x]:=tot;
        other[tot]:=y;
        len[tot]:=z;
    end;
         
    procedure init;
    var
        i, j                        :longint;
         
    begin
        read(n,m);
        for i:=1 to n do
            for j:=1 to m do num[i,j]:=(i-1)*m+j;
        for i:=1 to n do
            for j:=1 to m do
            begin
                read(key[i,j]);
                sum:=sum+key[i,j];
            end;
        for i:=1 to n+1 do
            for j:=1 to m do read(heng[i,j]);
        for i:=1 to n do
            for j:=1 to m+1 do read(shu[i,j]);
        source:=num[n,m]+2;
        sink:=source+1;
    end;
     
    function bfs:boolean;
    var
        q, p                        :longint;
        h, t, cur                   :longint;
    begin
        fillchar(d,sizeof(d),0);
        d[source]:=1;
        h:=0; t:=1; que[1]:=source;
        while h<t do
        begin
            inc(h);
            cur:=que[h];
            q:=last[cur];
            while q<>0 do
            begin
                p:=other[q];
                if (judge(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:longint;flow:extended):extended;
    var
        rest, tmp                   :extended;
        q, p                        :longint;
         
    begin
        if x=sink then exit(flow);
        rest:=flow;
        q:=last[x];
        while q<>0 do
        begin
            p:=other[q];
            if (judge(len[q])>0) and (d[p]=d[x]+1) and (rest>0) then
            begin
                tmp:=dinic(p,min(rest,len[q]));
                rest:=rest-tmp;
                len[q]:=len[q]-tmp;
                len[q xor 1]:=len[q xor 1]+tmp;
            end;
            q:=pre[q];
        end;
        exit(flow-rest);
    end;
     
    procedure main;
    var
        l, r, mid                   :extended;
        cur                         :longint;
        ans                         :extended;
        i, j                        :longint;
         
    begin
        l:=0; r:=90;
        while r-l>lim do
        begin
            mid:=(l+r)/2;
            fillchar(last,sizeof(last),0);
            tot:=1;
            for i:=1 to n do
                for j:=1 to m do
                begin
                    connect(source,num[i,j],key[i,j]);
                    connect(num[i,j],source,0);
                end;
             
            for i:=1 to n do
                for j:=1 to m do
                begin
                    cur:=0;
                    if i=1 then inc(cur,heng[i,j]);
                    if i=n then inc(cur,heng[i+1,j]);
                    if j=1 then inc(cur,shu[i,j]);
                    if j=m then inc(cur,shu[i,j+1]);
                    if cur>0 then
                    begin
                        connect(num[i,j],sink,cur*mid);
                        connect(sink,num[i,j],0);
                    end;
                end;
            for i:=1 to n-1 do
                for j:=1 to m do
                begin
                    connect(num[i,j],num[i+1,j],heng[i+1,j]*mid);
                    connect(num[i+1,j],num[i,j],heng[i+1,j]*mid);
                end;
            for i:=1 to n do
                for j:=1 to m-1 do
                begin
                    connect(num[i,j],num[i,j+1],shu[i,j+1]*mid);
                    connect(num[i,j+1],num[i,j],shu[i,j+1]*mid);
                end;
            ans:=0;
            while bfs do
                ans:=ans+dinic(source,maxlongint);
            if judge(sum-ans)>0 then l:=mid else r:=mid;
        end;
        writeln(l:0:3);
    end;
     
    begin
        init;
        main;
    end.

  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3500432.html
Copyright © 2011-2022 走看看