BZOJ2283: [Sdoi2011]火星移民
Description
在2xyz年,人类已经移民到了火星上。由于工业的需要,人们开始在火星上采矿。火星的矿区是一个边长为N的正六边形,为了方便规划,整个矿区被分为6*N*N个正三角形的区域(如图1)。
整个矿区中存在A矿,B矿,C矿三个矿场,和a厂,b厂,c厂三个炼矿厂。每个三角形的区域可以是一个矿场、炼矿厂、山地、或者平地。现在矿区管理局要求建立一个交通系统,使得矿场和对应炼矿厂之间存在一条公路,并且三条公路互不交叉(即一个三角形区域中不存在两条以上运输不同矿的公路)。两个三角形区域是相邻的当且仅当这两个三角形存在公共边,只有相邻的两个区域之间才能建一段路,建这段路的费用为1。注意,山地上是不能建公路的。由于火星金融危机的影响,矿区管理局想知道建立这样一个交通系统最少要花多少费用。更多的,当局向知道有多少种花费最小的方案。
Input
第1行一个整数N。表示这个矿区是边长为N的正六边形。
接下来有6*N*N的整数,分为2*N行,表示矿区当前区域的情况。0表示平地,1,2,3表示对应的矿区或者炼矿厂,4表示山地。(样例1对应图2)。可能有多组数据,请处理到文件结尾
Output
对于每组数据,包含两个整数,表示最小费用和达到最小费用的方案数。如果找不到符合要求的方案,输出-1 -1。由于方案数可能过大,所以请把方案数mod 1000000007
Sample Input
【样例输入1】
2
0 1 0 0 0
0 0 2 0 4 0 0
0 0 4 3 0 3 2
0 0 0 1 0
【样例输入2】
3
0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 3 0 0 0 0
0 0 0 0 0 0 0 0 0
0 3 0 1 0 2 0
2
0 1 0 0 0
0 0 2 0 4 0 0
0 0 4 3 0 3 2
0 0 0 1 0
【样例输入2】
3
0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 3 0 0 0 0
0 0 0 0 0 0 0 0 0
0 3 0 1 0 2 0
Sample Output
【样例输出1】
18 1
【样例输出2】
44 1
18 1
【样例输出2】
44 1
HINT
对于100%的数据,N≤6
恩恩。。什么插头dp ,看不懂,还不是具体做法up to具体题目啊。。。。
所以只好自己瞎YY了一个dp,练习了一下带hash的spfa版dp。。
具体就是两个三角形构成的平行四边形作为一个格子,预处理每个格子可以接受从左方和上方连过来的路径
以及与其相对应的连向右方和下方的 路径, 这也许就是插头吧,因为只有1,2,3或0(即没有路径连来)四种插头,
用四进制状压已宽搜出的状态之后 就可以一格一格的dp了。嘛 细节题
1 const ss=9875321; 2 const mo=1000000007; 3 const nn=10000000; 4 var 5 b:array[0..15,0..25]of longint; 6 a:array[0..15,0..25,0..3,0..3,0..3,0..3]of boolean; 7 ax:array[0..15,0..25,0..3,0..3,0..3,0..3]of longint; 8 d:array[0..nn]of longint; 9 g:array[0..ss,0..1]of longint; 10 next,u:array[0..nn,0..1]of longint; 11 f,w:array[0..nn,0..1]of longint; 12 e:array[0..nn,0..1]of boolean; 13 l,r,kk,qq,sx,sy,ii,jj,t1,t2,tt,i,j,n,m,k,t,x,y,z,p,q:longint; 14 procedure o(p,k,q,t:longint); 15 begin 16 ax[i,j,p,q,k,t]:=0; 17 if (b[i+1,j]<>0)and(k<>b[i+1,j])and(k<>0) then exit; 18 if (b[i,j+1]<>0)and(t<>b[i,j+1])and(t<>0) then exit; 19 a[i,j,p,q,k,t]:=true; 20 if (p+k>0)or((x>0)and(x<4)) then inc(ax[i,j,p,q,k,t]); 21 if (q+t>0)or((y>0)and(y<4)) then inc(ax[i,j,p,q,k,t]); 22 end; 23 function hash(x,t:longint):longint; 24 var i:longint; 25 begin 26 if t=tt then 27 begin 28 i:=x mod ss+1; 29 if u[g[i,t],t]=x then begin hash:=g[i,t]; g[i,t]:=next[g[i,t],t]; exit; end; 30 i:=g[i,t]; 31 while u[next[i,t],t]<>x do i:=next[i,t]; 32 hash:=next[i,t]; 33 next[i,t]:=next[next[i,t],t]; exit; 34 end; 35 i:=g[x mod ss+1,t]; 36 while (i<>0)and(u[i,t]<>x) do i:=next[i,t]; 37 if u[i,t]=x then exit(i); 38 inc(t2); i:=x mod ss+1; u[t2,t]:=x; 39 next[t2,t]:=g[i,t]; g[i,t]:=t2; exit(t2); 40 end; 41 begin 42 while true do 43 begin 44 fillchar(a,sizeof(a),0); 45 fillchar(b,sizeof(b),0); 46 fillchar(ax,sizeof(ax),0); 47 readln(n); if eof then exit; 48 x:=n*2+1; m:=n*4; 49 u[0,0]:=-1; u[0,1]:=-1; 50 for i:=0 to n+n+1 do 51 for j:=0 to m+1 do b[i,j]:=4; 52 for i:=1 to n do 53 begin 54 for j:=1 to x do read(b[i,j]); 55 x:=x+2; 56 end; 57 for i:=n+1 to n+n do 58 begin 59 x:=x-2; 60 for j:=m-x+1 to m do read(b[i,j]); 61 end; n:=n*2; readln; 62 for i:=1 to n do 63 for j:=1 to m do 64 if j and 1=0 then 65 begin 66 x:=b[i,j-1]; y:=b[i,j]; 67 if (x=0)and(y=0) then 68 begin 69 for p:=0 to 3 do begin o(0,0,p,p); o(0,p,p,0); o(0,p,0,p); o(p,0,0,p); o(p,0,p,0); o(p,p,0,0); end; 70 for p:=1 to 3 do for q:=1 to 3 do o(p,p,q,q); 71 end else 72 if (x=0)and(y<>4) then 73 begin 74 for p:=0 to 3 do begin o(p,p,y,0); o(p,p,0,y); end; 75 o(y,0,0,0); o(0,y,0,0); 76 end else 77 if (x=0)and(y=4) then 78 begin 79 for p:=0 to 3 do o(p,p,0,0); 80 end else 81 if (x<>4)and(y=0) then 82 begin 83 for p:=0 to 3 do begin o(x,0,p,p); o(0,x,p,p); end; 84 o(0,0,x,0); o(0,0,0,x); 85 end else 86 if (x<>4)and(y<>4) then 87 begin 88 o(x,0,y,0); o(x,0,0,y); o(0,x,y,0); o(0,x,0,y); 89 if x=y then o(0,0,0,0); 90 end else 91 if (x<>4)and(y=4) then 92 begin 93 o(x,0,0,0); o(0,x,0,0); 94 end else 95 if (x=4)and(y=0) then 96 begin 97 for p:=0 to 3 do o(0,0,p,p); 98 end else 99 if (x=4)and(y<>4) then 100 begin 101 o(0,0,y,0); o(0,0,0,y); 102 end else o(0,0,0,0); 103 end; 104 for i:=0 to nn do 105 for j:=0 to 1 do f[i,j]:=nn; 106 tt:=1; i:=hash(0,0); tt:=0; 107 f[i,0]:=0; w[i,0]:=1; e[i,0]:=true; 108 l:=1; r:=1; t:=2; p:=1; q:=2; kk:=1; t1:=1; t2:=0; 109 while true do 110 begin 111 while true do 112 begin 113 k:=hash(d[l],tt); 114 if q=2 then d[l]:=d[l]*4; 115 x:=(d[l]>>(q-2))and 3; 116 y:=(d[l]>>q)and 3; 117 sx:=d[l]-x<<(q-2)-y<<q; 118 for ii:=0 to 3 do 119 for jj:=0 to 3 do 120 if a[p,q,x,y,ii,jj] then 121 begin 122 qq:=sx+ii<<(q-2)+jj<<q; 123 z:=hash(qq,kk); 124 if f[z,kk]>f[k,tt]+ax[p,q,x,y,ii,jj] then 125 begin 126 f[z,kk]:=f[k,tt]+ax[p,q,x,y,ii,jj]; 127 w[z,kk]:=w[k,tt]; 128 if not e[z,kk] then 129 begin 130 e[z,kk]:=true; d[t]:=qq; inc(t); 131 if t=nn then t:=1; 132 end; 133 end else 134 if f[z,kk]=f[k,tt]+ax[p,q,x,y,ii,jj] then 135 begin 136 inc(w[z,kk],w[k,tt]); 137 if w[z,kk]>=mo then dec(w[z,kk],mo); 138 end; 139 end; 140 e[k,tt]:=false; w[k,tt]:=0; 141 f[k,tt]:=nn; 142 if l=r then break; 143 inc(l); if l=nn then l:=1; 144 end; 145 inc(l); if l=nn then l:=1; 146 if l=t then break; 147 if t=1 then r:=nn-1 else r:=t-1; tt:=kk; kk:=1-kk; t1:=t2; t2:=0; 148 if q=m then begin q:=2; inc(p); end else inc(q,2); 149 if p>n then break; 150 end; 151 i:=g[1,tt]; 152 while (i<>0)and(u[i,tt]<>0) do i:=next[i,tt]; 153 if i=0 then writeln('-1 -1') else 154 begin 155 writeln(f[i,tt]-3,' ',w[i,tt]); 156 end; 157 while l<>t do 158 begin 159 k:=hash(d[l],tt); 160 e[k,tt]:=false; w[k,tt]:=0; 161 f[k,tt]:=nn; 162 if l=r then break; 163 inc(l); if l=nn then l:=1; 164 end; 165 end; 166 end.
转载请标明出处 http://www.cnblogs.com/cyz666/