[BZOJ3698]XWW的难题解题报告|上下界网络流|有源汇最大流

XWW是个影响力很大的人,他有很多的追随者。这些追随者都想要加入XWW教成为XWW的教徒。但是这并不容易,需要通过XWW的考核。
XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XWW性。
称一个N*N的矩阵满足XWW性当且仅当:(1)A[N][N]=0;(2)矩阵中每行的最后一个元素等于该行前N-1个数的和;(3)矩阵中每列的最后一个元素等于该列前N-1个数的和。
现在你要给A中的数进行取整操作(可以是上取整或者下取整),使得最后的A矩阵仍然满足XWW性。同时XWW还要求A中的元素之和尽量大。

  首先很容易看出这是一个带上下界的网络流题...

  源点向代表每一行的点连边,代表每一列的点向汇点连边

  每一行向每一列连边,连的边就如前面无源汇可行流一样

  然后由于求的是最大流,二分答案

  每次从t→s连一条下限为mid的边

  

  问题来了..最后要输出的和最终的mid有什么关系呢...

  我们考虑这张图上的流量代表什么

  我们连的边代表的刚开始没有考虑下限的边所以认为是波动的数值

  然而实际上很简单就是每个格子的数值

  最后输出的答案是整张图的数值

  每个点在自己位置、行末和列末各统计一次

  所以乘上3输出就可以了

  

  因为INF设得过小WA了两次...

program zoj2314;
const maxn = 2100;maxm = 800010;INF = 100000007;
var fa,next,ter,w,rec,flow:array[-1..maxm]of longint;
    link,dis,opt,inp:array[-1..maxn]of longint;
    vis:array[-1..maxn]of boolean;
    n,m,e,tt,test,i,s,t,x,y,l,r,j,mid,sum,lx,rx,ans:longint;
    a:array[-1..maxn,-1..maxn]of extended;

function min(a,b:longint):longint;
begin
        if a<b then exit(a) else exit(b);
end;

function spfa:boolean;
var head,tail,x,j:longint;
begin
    fillchar(vis,sizeof(vis),true);
    fillchar(dis,sizeof(dis),63);
    head:=0;tail:=1;opt[1]:=s;vis[s]:=false;dis[s]:=0;
    while head<>tail do
    begin
        head:=(head+1) mod maxn;
        x:=opt[head];j:=link[x];
        while j<>0 do
        begin
            if (dis[x]+1<dis[ter[j]])and(w[j]>0) then
            begin
                dis[ter[j]]:=dis[x]+1;
                if vis[ter[j]] then
                begin
                    vis[ter[j]]:=false;
                    tail:=(tail+1) mod maxn;
                    opt[tail]:=ter[j];
                end;
            end;
            j:=next[j];
        end;
        vis[x]:=true;
    end;
    if dis[t]<>dis[t+1] then exit(true) else exit(false);
end;

function dfs(p,sum:longint):longint;
var tem,j,x:longint;
begin
    tem:=0;
    if p=t then exit(sum);
    j:=link[p];
    while j<>0 do
     begin
        if (dis[ter[j]]=dis[p]+1)and(w[j]>0) then
        begin
            x:=dfs(ter[j],min(sum-tem,w[j]));
            inc(tem,x);dec(w[j],x);inc(w[rec[j]],x);
            if rec[j]=j+1 then inc(flow[fa[j]],x) else dec(flow[fa[rec[j]]],x);
            if tem=sum then exit(sum);
        end;
        j:=next[j];
    end;
    exit(tem);
end;

procedure add(x,y,z:longint);
begin
    inc(e);ter[e]:=y;next[e]:=link[x];link[x]:=e;w[e]:=z;rec[e]:=e+1;
    inc(e);ter[e]:=x;next[e]:=link[y];link[y]:=e;w[e]:=0;rec[e]:=e-1;
end;

function Jud:boolean;
var j:longint;
begin
    j:=link[s];
    while j<>0 do
    begin
        if w[j]>0 then exit(false);
        j:=next[j];
    end;
    exit(true);
end;

function Solve:boolean;
var i,sum:longint;
begin
        sum:=0;
    while spfa do inc(sum,dfs(s,1000000007));
    if (not Jud) then exit(false) else exit(true);
end;

begin
    readln(n);ans:=0;
    for i:=1 to n do
    begin
        for j:=1 to n do begin read(a[i,j]);inc(ans,trunc(a[i,j]));end;
        readln;
    end;
    Lx:=0;Rx:=10000000007;sum:=-1;
    while Lx<=Rx do
    begin
        mid:=(Lx+Rx) >> 1;
        fillchar(next,sizeof(next),0);
        fillchar(link,sizeof(link),0);
        fillchar(inp,sizeof(inp),0);
        e:=0;s:=0 ;t:=2*n+1;
        for i:=1 to n-1 do
        begin
            l:=trunc(a[i,n]);
            if a[i,n]<>l then add(s,i,1);
            dec(inp[s],l);inc(inp[i],l);

            l:=trunc(a[n,i]);
            if a[n,i]<>l then add(n+i,t,1);
            dec(inp[n+i],l);inc(inp[t],l);
        end;
        for i:=1 to n-1 do
            for j:=1 to n-1 do
            begin
                l:=trunc(a[i,j]);
                if a[i,j]<>l then add(i,n+j,1);
                dec(inp[i],l);inc(inp[n+j],l);
            end;
        add(t,s,INF);
                inc(inp[s],mid);dec(inp[t],mid);
        dec(s);inc(t);
        for i:=s+1 to t-1 do
        if inp[i]>0 then add(s,i,inp[i]) else
        if inp[i]<0 then add(i,t,-inp[i]);
        if Solve then begin sum:=mid;Lx:=mid+1 end else Rx:=mid-1;
    end;
        writeln(sum*3);
end.

  

时间: 2024-08-29 19:50:23

[BZOJ3698]XWW的难题解题报告|上下界网络流|有源汇最大流的相关文章

zoj 3229 dinic算法的非递归实现以及有上下界的有源汇的网络流的最大流的求解

Shoot the Bullet Time Limit: 2 Seconds      Memory Limit: 32768 KB      Special Judge Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utopia where humans and other beings such as fairies, youkai(phantoms)

bzoj3698 XWW的难题

题意:给你个n * n的实数矩阵,你需要把它中的每个数上/下取整,并满足如下条件: 每行最后一个数等于前面的和. 每列最后一个数等于前面的和. n行n列的那个元素始终为0,不予考虑. 求满足条件下矩阵中元素的最大总和是多少. 解: 首先假设全部下取整. s->行->列->t连边,可以发现每条边都有上下界. 有源汇有上下界最大流. 出来的最大流*3就是答案. 1 #include <cstdio> 2 #include <algorithm> 3 #include

【有上下界网络流】【ZOJ】2314 Reactor Cooling

[算法]有上下界网络流-无源汇(循环流) [题解] 无源汇网络流相当于重建图后跑最大流. 循环流要求每个点(或边)的流入量和流出量相等. http://www.cnblogs.com/liu-runda/p/6262832.html http://hzwer.com/3356.html 入度>出度时(in[x]>0)时,需要流出去,所以从源向点引一条边,引诱它流出去. 入度<出度时(in[x]<0)时,需要流进来,所以从点向汇引一条边,引诱它流进来. 为何这样正确?源和汇的作用只是

洛谷OJ P1379 八数码难题 解题报告

洛谷OJ P1379 八数码难题 解题报告 by MedalPluS 题目描述   在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变.   输入格式   输入初试状态,一行九个数字,空格用0表示   输出格式 只有一行,该行只有一个数字,表示从初始状态到

有上下界的网络流2-有源汇带上下界网络流ZOJ3229

ZOJ3229题目大意:一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝可以和C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌丝最多能拍多少张照,并求每天给对应女神拍多少张照:否则输出-1. 解题思路:        1.增设一源点st,汇点sd,st到第i天连一条上界为Di下界为0的边,每个女神到汇点连一条下界为Gi上界为正无穷的边,对于每一天,当天到第i个女孩连一条[Li,Ri]的边.        2.

acdream 1211 Reactor Cooling 【上下界网络流 + 输出流量】

题目:acdream 1211 Reactor Cooling 分类:无源无汇的有上下界网络流. 题意: 给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质. 并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li. 例如: 46(4个点,6个pipe) 12 1 3 (1->2上界为3,下界为1) 23 1 3

上下界网络流总结

1.无源汇上下界可行流 对于(u,v)有向边,上界为a,下界为b 构图方法为: (1) ss 到 v 容量为 b (2) u 到 tt 容量为 b (3) u 到 v 容量为 a-b 求ss-tt最大流,当且仅当 maxflow=sigma(i,t)=sigma(s,i) 时 存在可行流 2.有源汇上下界最小流 如果发现原图无源汇,要先转化为有源汇 其他点如1方法,建图,另加 t-s 容量为 inf 求一遍 ss-tt最大流,此时s-t的流量为 t-s这条边的反向边的流量,记为 x 在残量网络中

ZOJ 2314 Reactor Cooling 无源汇有上下界网络流

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题意:给出N个点,M条边的有向图,每条边的有上下界规定,问是否存在一个可行流满足条件,如果满足输出YES并输出每条边的流量. 如果不满足输出NO. 根据周源的<一种简易的方法求解流量有上下界的网络中网络流问题> 无源汇上下界网络流的做法是: 设边u->v的下界是B(u,v),上界是C(u,v). 设M(i)为对于i结点的流入i的下界总和-流出i的下界总

ZOJ Problem Set - 3229 Shoot the Bullet 【有上下界网络流+流量输出】

题目:ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇有上下界网络流 题意:有 n 天和 m 个girls,然后每天给一部分girls拍照,每个girls 有拍照的下限,即最少要拍这么多张,然后每天有k个女孩拍照,摄影师最多可以拍num张,然后 k 个女该每天拍照数量值有上下限,然后问你有没有满足这样条件的给女孩拍照的最大方案,然后按照输入输出每天给女孩拍照的张数. 做这道题目推荐先做:这儿 分析:首先它让你判断能不能满足条件. 按照题目给出的条件很