题的大概意思就是给定一个无向图,边有权值,现在你有k个人在0点,要求走到n点,且满足

1:人们可以分头行动,可以停在某一点不走了

2:当你走到x时,前x-1个点必须全部走过(不同的人走过也行,即分两路走,其中一路走过1-x-1点

,另一路可以走x点)

3:道路可以多次走,点在满足2的情况下可以多次经过

求所有人走过的总路程最短

这道题历尽挫折。。。

首先我们知道想要走到x点,一定是从前x-1个点走过来,假设我们从y走过来,y<x,那么y走到x一定走的

是可以走的最短路,既然可以走x了,那么前x-1个点一定已经走过了,所以y到x的最短路就是当图只有前x点

时的y到x的最短路,那么我们可以用floyd解决,设d[k,i,j]代表只走前K个点,I到J的最短路,那么循环时,最

外层是k,直接记录d[k,i,j]就行了,因为当循环到K时,只用前K个更新过I到J的最短路,所以I到J只会走前K个点

,这时的d[i,j]就是d[k,i,j]了

那么我们对于这道题拆点,每个点拆成Ai,Bi,添加源S,汇T

规定(a,b,c,d)为连接a到b,容量为c,费用为d的有向边

那么我们先(Ai,Bi,1,0)代表这一个点被经过一次,因为每个点有效经过只有一次,下文具体解释

然后(S,0,k,0),代表从0开始走,一共可以走k个人

然后(Bi,T,1,0),代表一个人最终停在点I,就相当于这个流没用了,直接流出

然后我们对于每个点I,肯定会从之前的一个点走过来,这就是开始说的floyd处理的过程了,每个J,0<=j<i连向I

(J,I,1,d[I,J,I])

那么这么建的正确性到现在还没有保证,因为题中要求每个点都要被走过,这里只是连边时费用应用了下这个性质,但是

做费用流的时候是没法保证的(就是可能有的点不会被流过),那么Ai连Bi代表这个点被流过,那么我们规定必须流这个边就行了,

也就是经常说的流量的上下界(上界就是容量),规定Ai到Bi的上下界流量都为1

那么具体怎么做,假设对于点A到B规定上界为U(p),下界为D(own),那么我们一定会至少流U的,所以剩下的就是D-U,我们

将这条边的流量设为D-U,可这样流量平衡等式就不满足了,也就是A点应该多流出D的,B应该多流入D的,所以添加新的源点X,

汇点Y,(A,x,D,0),(y,B,D,0),(x,y,INF,0)也就是说我们把规定必须流的从X引走然后又流到Y了,这样就行了

对于下界还有一个二分的做法,内个不会。。。

然后这道题可以不用这么麻烦,可以将Ai到Bi的边的费用设成-INF,那么因为我们是最短路找增广路的,所以一定会走这一条边,

然后就好些很多了

对于这道题,还有另一种建图的方式,也是先拆点

然后没有0这个点

加入X,Y点

(s,Y,1,0)代表从0开始走,(Y,X,K,0)代表最多走K个人,

然后拆的点(Ai,Bi,-inf,0),(Bi,Aj,1,d[j,i,j])和上一种建图代表的一样,然后我们Y,X起的是0的作用

所以(X,Ai,1,d[i,0,i]]),然后再(Ai,T,1,0),代表走到I不走了

但是光这样建,如果K比N小的时候只会流K个,有的点流不到(上一种方法用的下界解决的),那么这时

(S,Bi,1,0)代表从0,走的人,之后去哪儿,这样直接求就行了。

还有地方可以优化,就是floyd的时候,不用三维数组存,最外层每循环一次直接连边就行了。

附两种图的代码

/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ //By BLADEVIL
var
n, m, k :longint;
x, y, ss, st :longint;
l :longint;
d :array[..,..] of longint;
a, b, c :longint;
pre, other, len, cost :array[..] of longint;
last :array[..] of longint;
ans :longint;
dis, father :array[..] of longint;
flag :array[..] of boolean;
que :array[..] of longint; 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; function spfa:boolean;
var
h, t, q, p :longint;
cur :longint; begin
filldword(dis,sizeof(dis) div ,maxlongint div );
que[]:=ss; dis[ss]:=;
h:=; t:=;
while h<>t do
begin
h:=h mod +;
cur:=que[h];
flag[cur]:=false;
q:=last[cur];
while q<> do
begin
p:=other[q];
if len[q]> 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 +;
que[t]:=p;
flag[p]:=true;
end;
end;
end;
q:=pre[q];
end;
end;
if dis[st]=maxlongint div then exit(false) else exit(true);
end; procedure update;
var
low :longint;
cur :longint;
begin
low:=maxlongint;
cur:=st;
while cur<>ss do
begin
low:=min(low,len[father[cur]]);
cur:=other[father[cur] xor ];
end;
cur:=st;
while cur<>ss do
begin
dec(len[father[cur]],low);
inc(len[father[cur] xor ],low);
if cost[father[cur]]<>-maxlongint div then
inc(ans,low*cost[father[cur]]);
cur:=other[father[cur] xor ];
end;
end; procedure init;
var
i, j :longint;
begin
read(n,m,k);
x:=*n+; y:=x+; ss:=y+; st:=ss+;
l:=;
connect(ss,,k,); connect(,ss,,);
for i:= to n do
begin
connect(*i,*i+,,-maxlongint div );
connect(*i+,*i,,maxlongint div );
connect(*i+,st,,); connect(st,*i+,,);
end;
filldword(d,sizeof(d) div ,maxlongint div );
for i:= to n do d[i,i]:=;
for i:= to m do
begin
read(a,b,c);
if c<d[a,b] then
begin
d[a,b]:=c; d[b,a]:=c;
end;
end;
for k:= to n do
begin
for i:= to n do
for j:= to n do
d[i,j]:=min(d[i,j],d[i,k]+d[k,j]);
connect(,*k,,d[,k]); connect(*k,,,-d[,k]);
for i:= to k- do
begin
connect(*i+,*k,,d[i,k]);
connect(*k,*i+,,-d[i,k]);
end;
end;
end; procedure main;
begin
while spfa do
update;
writeln(ans);
end; begin
init;
main;
end.
/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ //By BLADEVIL
var
n, m, k :longint;
x, y, ss, st :longint;
l :longint;
d :array[..,..] of longint;
a, b, c :longint;
pre, other, len, cost :array[..] of longint;
last :array[..] of longint;
ans :longint;
dis, father :array[..] of longint;
flag :array[..] of boolean;
que :array[..] of longint; 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; function spfa:boolean;
var
h, t, q, p :longint;
cur :longint; begin
filldword(dis,sizeof(dis) div ,maxlongint div );
que[]:=ss; dis[ss]:=;
h:=; t:=;
while h<>t do
begin
h:=h mod +;
cur:=que[h];
flag[cur]:=false;
q:=last[cur];
while q<> do
begin
p:=other[q];
if len[q]> 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 +;
que[t]:=p;
flag[p]:=true;
end;
end;
end;
q:=pre[q];
end;
end;
if dis[st]=maxlongint div then exit(false) else exit(true);
end; procedure update;
var
low :longint;
cur :longint;
begin
low:=maxlongint;
cur:=st;
while cur<>ss do
begin
low:=min(low,len[father[cur]]);
cur:=other[father[cur] xor ];
end;
cur:=st;
while cur<>ss do
begin
dec(len[father[cur]],low);
inc(len[father[cur] xor ],low);
inc(ans,low*cost[father[cur]]);
cur:=other[father[cur] xor ];
end;
end; procedure init;
var
i, j :longint;
begin
read(n,m,k);
x:=*n+; y:=x+; ss:=y+; st:=ss+;
l:=;
for i:= to n do
begin
connect(i,i+n,,); connect(i+n,i,,);
connect(i+n,y,,); connect(y,i+n,,);
connect(ss,i+n,,); connect(i+n,ss,,);
connect(i,st,,); connect(st,i,,);
end;
connect(y,x,k,); connect(x,y,,);
filldword(d,sizeof(d) div ,maxlongint div );
for i:= to n do d[i,i]:=;
for i:= to m do
begin
read(a,b,c);
if c<d[a,b] then
begin
d[a,b]:=c; d[b,a]:=c;
end;
end;
for k:= to n do
begin
for i:= to n do
for j:= to n do
d[i,j]:=min(d[i,j],d[i,k]+d[k,j]);
connect(x,k,,d[,k]); connect(k,x,,-d[,k]);
for i:= to k- do
begin
connect(i+n,k,,d[i,k]);
connect(k,i+n,,-d[i,k]);
end;
end;
end; procedure main;
begin
while spfa do
update;
writeln(ans);
end; begin
init;
main;
end.

bzoj 2324 ZJOI 营救皮卡丘 费用流的更多相关文章

  1. BZOJ.2324.[ZJOI2011]营救皮卡丘(费用流 Floyd)

    BZOJ 洛谷 首先预处理出\(dis[i][j]\),表示从\(i\)到\(j\)的最短路.可以用\(Floyd\)处理. 注意\(i,j\)是没有大小关系限制的(\(i>j\)的\(dis[ ...

  2. bzoj 2324 [ZJOI2011]营救皮卡丘(floyd,费用流)

    2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1777  Solved: 712[Submit][Stat ...

  3. BZOJ 2324: [ZJOI2011]营救皮卡丘( floyd + 费用流 )

    昨晚写的题...补发一下题解... 把1~N每个点拆成xi, yi 2个. 预处理i->j经过编号不超过max(i,j)的最短路(floyd) S->0(K, 0), S->xi(1 ...

  4. bzoj2324 [ZJOI2011]营救皮卡丘 费用流

    [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2653  Solved: 1101[Submit][Status][D ...

  5. BZOJ 2324: [ZJOI2011]营救皮卡丘(带上下限的最小费用最大流)

    这道题么= =还是有些恶心的,第一次写带上下界的网络流,整个人都萌萌哒~~~ 首先先预处理得最短路后 直接用费用流做就行了。 第一次写,还是挺好写的= = CODE: #include<cstd ...

  6. bzoj 2324: [ZJOI2011]营救皮卡丘

    #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #inclu ...

  7. 【BZOJ 2324】[ZJOI2011]营救皮卡丘 费用流

    本人实行诱骗拐卖(利用自然分层与实际意义),正解拼接补充(充分利用最大流限制(不浪费任何一个走出去的机会而不是不浪费任何一个已有的流)与问题转换) #include <cstdio> #i ...

  8. BZOJ-2324 营救皮卡丘 最小费用可行流+拆下界+Floyd预处理

    准备一周多的期末,各种爆炸,回来后状态下滑巨快...调了一晚上+80%下午 2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MB ...

  9. BZOJ2324: [ZJOI2011]营救皮卡丘

    2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1359  Solved: 522[Submit][Stat ...

随机推荐

  1. Qt 绘制汽车仪表 指针旋转锯齿问题

    在前面几篇中出现的问题 http://blog.csdn.net/z609932088/article/details/53946245 这个是在QWidget下绘制的,出现了指针有锯齿的问题 后面开 ...

  2. Qt 隐藏标题栏可移动升级版

    在最出的时候,在Qt程序隐藏标题栏的情况下,实现界面可拖拽移动,是鼠标在在程序界面的任意位置都可以,现在这个版本是需要鼠标在程序界面的特定位置开可以 上代码 static QPoint last(0, ...

  3. 《python核心编程第二版》第3章习题

    3-1. 标识符.为什么 Python 中不需要变量名和变量类型声明? 答: 对象的类型和内存占用都是运行时确定的. 尽管代码被编译成字节码,Python 仍然是一种解释 型语言. 在创建也就是赋值时 ...

  4. 第十二篇 Python函数之全局变量&局部变量&递归函数

    全局变量:在定义的时候,顶头写的,没有任何缩进的变量就是全局变量. 全局变量的特点:在当前文件里的任何地方都可以进行调用 局部变量:在子程序里定义的变量,就是局部变量. 子程序:比如.py文件里,写的 ...

  5. selenium 的安装使用

    直接pip安装 pip install selenium 默认是火狐浏览器,需要安装下面网址的软件,解压后加入到环境变量中就可以了 https://github.com/mozilla/geckodr ...

  6. Android Studio环境解读

    一.使用IDE开发APP的流程 要熟悉一个新的IDE,可依次完成以下流程: 二.相关术语解析 Dalvik: Android特有的虚拟机,和JVM不同,Dalvik虚拟机非常适合在移动终端上使用! A ...

  7. Hadoop执行bin/stop-all.sh时no namenode to stop异常

    1 先关闭hadoop所有服务 命令: bin/stop-all.sh 2 格式化namenode 命令: bin/hadoop namenode -format 3 重新启动所有服务 命令: bin ...

  8. OpenCV彩色图像转灰度图

    核心函数cvSplit(). #include<cv.h> #include<highgui.h> int main(int argc, char** argv) { IplI ...

  9. SSH答疑解惑系列(二)——java.lang.reflect.InvocationTargetException异常

    在项目中遇到了invocationTargetException的问题,在这里跟大家分享一下. 报错信息如下: 使用反射时,比如执行invoke方法,如果被反射执行的方法体抛出了Exception,这 ...

  10. Java 对象及其内存控制

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 更新:其实这里有好多的变戏法,只要你理解了他们在JVM的中的实现机制,就豁然开朗了.有时间我会把这些变戏法的东西 ...