Bzoj2595: [Wc2008]游览计划
2016-09-13 11:17
387 查看
原题网址:http://www.lydsy.com/JudgeOnline/problem.php?id=2595
标算是斯坦纳树,其实类似状压dp。
首先答案一定是树形的,否则断开一条环上边,不影响连通性,答案不会变劣。
用f[x][y][s]表示以x,y为根的,经过了至少 s的景点的树,这里的s是压过的0/1表示的景点是否访问过的状态。
有两种状态转移,一种是合并两棵树f[x][y][s]:=f[x][y][t]+f[x][y][s xor t]-cost[x][y](其中t是s的真子集),另一种是换根f[x’][y’]:=f[x][y]+cost[x’][y’]。
其中有一个技巧是枚举真子集时一开始t:=s;每次t:=(t-1) and s;就能得到一个真子集,结束条件是t=0。
由于我是个蒟蒻,所以有两个错调了好久,一个是循环队列head<>tail写成了head< tail;还有一个是在同一层s内的搜索要拿x,y更新tx,ty才符合正常的搜索顺序,我居然写反了。。。
标算是斯坦纳树,其实类似状压dp。
首先答案一定是树形的,否则断开一条环上边,不影响连通性,答案不会变劣。
用f[x][y][s]表示以x,y为根的,经过了至少 s的景点的树,这里的s是压过的0/1表示的景点是否访问过的状态。
有两种状态转移,一种是合并两棵树f[x][y][s]:=f[x][y][t]+f[x][y][s xor t]-cost[x][y](其中t是s的真子集),另一种是换根f[x’][y’]:=f[x][y]+cost[x’][y’]。
其中有一个技巧是枚举真子集时一开始t:=s;每次t:=(t-1) and s;就能得到一个真子集,结束条件是t=0。
由于我是个蒟蒻,所以有两个错调了好久,一个是循环队列head<>tail写成了head< tail;还有一个是在同一层s内的搜索要拿x,y更新tx,ty才符合正常的搜索顺序,我居然写反了。。。
const dx:array[1..4] of longint=(0,0,-1,1); dy:array[1..4] of longint=(-1,1,0,0); INF=maxlongint>>1; mx=101; type rec=record x,y,s:longint; end; var f,cnt:array[1..10,1..10,0..1024] of longint; hash:array[0..10,0..10,0..1024] of boolean; map:array[1..10,1..10] of boolean; pre:array[1..10,1..10,0..1024,0..1] of rec; a:array[1..10,1..10] of longint; q:array[0..1024] of longint; vis:array[0..1024] of boolean; n,m,e,x,y,k,head,tail,s,t,ans,ansx,ansy,i,line,tot:longint; procedure SPFA(s:longint); var vis:array[1..10,1..10] of boolean; q:array[0..mx] of rec; head,tail,x,y,k,tx,ty:longint; begin try fillchar(vis,sizeof(vis),false); head:=1;tail:=1;tot:=0; for x:=1 to n do for y:=1 to m do for k:=1 to 4 do begin tx:=x+dx[k]; ty:=y+dy[k]; if (tx<1)or(ty<1)or(tx>n)or(ty>m) then continue; if f[x][y][s]+a[tx][ty]<f[tx][ty][s] then begin f[tx][ty][s]:=f[x][y][s]+a[tx][ty]; cnt[tx][ty][s]:=0; pre[tx][ty][s][0].x:=x; pre[tx][ty][s][0].y:=y; pre[tx][ty][s][0].s:=s; if not vis[tx][ty] then begin vis[tx][ty]:=true; q[tail].x:=tx; q[tail].y:=ty; inc(tail);if tail>mx then tail:=1; end; end; end; while head<>tail do begin x:=q[head].x; y:=q[head].y; inc(head);if head>mx then head:=1; for k:=1 to 4 do begin tx:=x+dx[k]; ty:=y+dy[k]; if (tx<1)or(ty<1)or(tx>n)or(ty>m) then continue; if f[x][y][s]+a[tx][ty]<f[tx][ty][s] then begin f[tx][ty][s]:=f[x][y][s]+a[tx][ty]; cnt[tx][ty][s]:=0; pre[tx][ty][s][0].x:=x; pre[tx][ty][s][0].y:=y; pre[tx][ty][s][0].s:=s; if not vis[tx][ty] then begin vis[tx][ty]:=true; q[tail].x:=tx; q[tail].y:=ty; inc(tail);if tail>mx then tail:=1; end; end; end; vis[x][y]:=false; end; end; procedure dfs(x,y,s:longint); var i:longint; begin if (x=0)or(hash[x][y][s]) then exit; map[x][y]:=true; hash[x][y][s]:=true; for i:=0 to cnt[x][y][s] do dfs(pre[x][y][s][i].x,pre[x][y][s][i].y,pre[x][y][s][i].s); end; begin assign(input,'trip.in');reset(input); assign(output,'trip.out');rewrite(output); read(n,m);e:=-1; for x:=1 to n do for y:=1 to m do for k:=0 to 1<<10-1 do f[x][y][k]:=INF; for x:=1 to n do for y:=1 to m do begin read(a[x][y]); if a[x][y]=0 then begin inc(e); f[x][y][1<<e]:=a[x][y]; end; end; for x:=1 to n do for y:=1 to m do f[x][y][0]:=a[x][y]; head:=1;tail:=2; q[1]:=0;vis[0]:=true; while head<tail do begin s:=q[head]; for x:=1 to n do for y:=1 to m do begin t:=s;t:=(t - 1) and s; while t>0 do begin if f[x][y][t]+f[x][y][s xor t]-a[x][y]<f[x][y][s] then begin f[x][y][s]:=f[x][y][t]+f[x][y][s xor t]-a[x][y]; cnt[x][y][s]:=1; pre[x][y][s][0].x:=x; pre[x][y][s][0].y:=y; pre[x][y][s][0].s:=t; pre[x][y][s][1].x:=x; pre[x][y][s][1].y:=y; pre[x][y][s][1].s:=s xor t; end; t:=(t - 1) and s; end; end; SPFA(s); for i:=0 to e do if (s and 1 << i=0)and(not vis[s xor 1<<i]) then begin vis[s xor 1<<i]:=true; q[tail]:=s xor 1 << i; inc(tail); end; inc(head); end; ans:=maxlongint; for x:=1 to n do for y:=1 to m do if f[x][y][1<<(e+1)-1]<ans then begin ans:=f[x][y][1<<(e+1)-1]; ansx:=x; ansy:=y; end; if e>=0 then writeln(ans) else writeln(0); if e>=0 then dfs(ansx,ansy,1<<(e+1)-1); for x:=1 to n do begin for y:=1 to m do if a[x][y]=0 then write('x') else if map[x][y] then write('o') else write('_'); writeln; end; close(input);close(output); end.
相关文章推荐
- BZOJ2595 [Wc2008]游览计划
- 【WC2008】bzoj2595 游览计划
- Bzoj2595: [Wc2008]游览计划
- BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树
- 【BZOJ2595】【Wc2008】游览计划、斯坦纳树
- BZOJ 2595: [Wc2008]游览计划(斯坦纳树)
- bzoj2595 [Wc2008]游览计划
- BZOJ2595 [Wc2008]游览计划
- 【BZOJ 2595】【WC 2008】游览计划
- BZOJ 2595: [Wc2008]游览计划
- bzoj2595 [Wc2008]游览计划
- BZOJ2595 Wc2008 游览计划
- bzoj2595 [Wc2008]游览计划(最小斯坦纳树(状压DP))
- [BZOJ2595][Wc2008]游览计划(斯坦纳树)
- BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】
- 【bzoj2595】[Wc2008]游览计划 斯坦纳树
- BZOJ2595:[Wc2008]游览计划——题解(插头dp)
- 【BZOJ2595】[Wc2008]游览计划 斯坦纳树
- 斯坦纳树 [bzoj2595][wc2008]游览计划 题解
- bzoj:2595: [Wc2008]游览计划