首页 > 代码库 > BZOJ3876[AHOI2014]支线剧情
BZOJ3876[AHOI2014]支线剧情
Description
【故事背景】
宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等。不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情。
这些游戏往往都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情。
【问题描述】
JYY现在所玩的RPG游戏中,一共有N个剧情点,由1到N编号,第i个剧情点可以根据JYY的不同的选择,而经过不同的支线剧情,前往Ki种不同的新的剧情点。当然如果为0,则说明i号剧情点是游戏的一个结局了。
JYY观看一个支线剧情需要一定的时间。JYY一开始处在1号剧情点,也就是游戏的开始。显然任何一个剧情点都是从1号剧情点可达的。此外,随着游戏的进行,剧情是不可逆的。所以游戏保证从任意剧情点出发,都不能再回到这个剧情点。由于JYY过度使用修改器,导致游戏的“存档”和“读档”功能损坏了,
所以JYY要想回到之前的剧情点,唯一的方法就是退出当前游戏,并开始新的游戏,也就是回到1号剧情点。JYY可以在任何时刻退出游戏并重新开始。不断开始新的游戏重复观看已经看过的剧情是很痛苦,JYY希望花费最少的时间,看完所有不同的支线剧情。
Input
输入一行包含一个正整数N。
接下来N行,第i行为i号剧情点的信息;
第一个整数为,接下来个整数对,Bij和Tij,表示从剧情点i可以前往剧
情点,并且观看这段支线剧情需要花费的时间。
Output
输出一行包含一个整数,表示JYY看完所有支线剧情所需要的最少时间。
Sample Input
6
2 2 1 3 2
2 4 3 5 4
2 5 5 6 6
0
0
0
2 2 1 3 2
2 4 3 5 4
2 5 5 6 6
0
0
0
Sample Output
24
HINT
对于100%的数据满足N<=300,0<=Ki<=50,1<=Tij<=300,Sigma(Ki)<=5000
题解:
这题有点类似BZOJ2324[ZJOI2011]营救皮卡丘,不过此题要求访问每一条边,而非每一个点。
将每个点i拆成i1与i2,增加i1——>i2的边,容量为inf,费用为0。
对于出度为x的拓扑节点i,增加x条i2——>T的边,容量为1,费用为对应出边的边权,表示这x条边都要被访问。
对于入度为x的节点i,增加1条S——>i1的边,容量为x,费用为0,表示这x条入边被访问后,都可以视为从该点重新出发。
对于点对(i,j),若i点可以到达j点,则增加i1——>j2的边,容量为inf,费用为距离,表示从i点出发走到j点,从而可以访问某个从j点引发的剧情。
设起点为R,添加一条S——>R1的边,容量为inf,费用为0,表示从起点出发。
这样建图后,跑一遍zkw费用流即可。
代码:
var o,v:array[0..1600] of boolean; f,s,d,dis:array[0..1600] of longint; next,p,c,w:array[-100000..100000] of longint; i,j,k,l,y,t,tt,ft,n,ff,st,sf,ans,imp,new,flow:longint; a:array[0..301,0..301]of longint; tot:array[0..301]of longint; procedure link(i,j,k,l:longint); begin inc(t); next[t]:=d[i]; d[i]:=t; p[t]:=j; c[t]:=k; w[t]:=l; next[-t]:=d[j]; d[j]:=-t; p[-t]:=i; w[-t]:=-l; end; function dfs(i,flow:longint):longint; var j,k,l,min:longint; begin if i=tt then begin inc(ans,dis[i]*flow); exit(flow); end; k:=s[i]; j:=p[k]; dfs:=0; o[i]:=true; v[i]:=true; while k<>0 do begin l:=dis[i]+w[k]-dis[j]; min:=flow; if c[k]<min then min:=c[k]; if(min>0)and(l<f[j])then f[j]:=l; if(min>0)and(l=0)and(not o[j])then begin l:=dfs(j,min); inc(dfs,l); dec(flow,l); dec(c[k],l); inc(c[-k],l); end; if flow=0 then break; s[i]:=next[s[i]]; k:=s[i]; j:=p[k]; end; o[i]:=false; end; begin readln(n); tt:=2*n+1; for i:=1 to n do for j:=1 to n do a[i,j]:=maxlongint div 2; for i:=1 to n do begin read(k); for j:=1 to k do begin read(l,y); a[i,l]:=y; inc(tot[l]); link(i,2*n+1,1,y); end; end; for k:=1 to n do for i:=1 to n do for j:=1 to n do if a[i,k]+a[k,j]<a[i,j] then a[i,j]:=a[i,k]+a[k,j]; for i:=1 to n do for j:=1 to n do if(i<>j)and(a[i,j]<maxlongint div 2)then link(i+n,j,1 shl 20,a[i,j]); link(0,1+n,1 shl 20,0); for i:=1 to n do link(0,i+n,tot[i],0); for i:=1 to n do link(i+n,i,1 shl 20,0); repeat for i:=0 to tt do s[i]:=d[i]; fillchar(v,sizeof(v),false); fillchar(f,sizeof(f),1); inc(flow,dfs(0,1 shl 20)); imp:=1 shl 20; for i:=0 to tt do if(not v[i])and(f[i]<imp)then imp:=f[i]; for i:=0 to tt do if not v[i] then inc(dis[i],imp); until imp=1 shl 20; writeln(ans); end.
BZOJ3876[AHOI2014]支线剧情
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。