# bzoj2595

f[x,y,S]=min(f[x,y,s']+f[x,y,S-s']-a[x,y]) S'是S的一个子集，相当于合并两个数

f[x,y,S]=min(f[x',y',S]+a[x,y]) (x',y')与(x,y)相邻

  1 const dx:array[1..4] of longint=(0,0,1,-1);
2       dy:array[1..4] of longint=(1,-1,0,0);
3       inf=1000000007;
4 type node=record
5        x,y,k:longint;
6      end;
7
8 var q:array[0..1000010] of node;
9     pre:array[0..11,0..11,0..1025] of node;
10     f:array[0..11,0..11,0..1025] of longint;
11     v:array[0..11,0..11] of boolean;
12     a:array[0..11,0..11] of longint;
13     t,h,r,k,i,j,s,n,m,x,y:longint;
14
15 function make(i,j,k:longint):node;
16   begin
17     make.x:=i;
18     make.y:=j;
19     make.k:=k;
20   end;
21
22 procedure spfa(k:longint);
23   var i,x,y,x0,y0:longint;
24   begin
25     while h<=r do
26     begin
27       x0:=q[h].x; y0:=q[h].y;
28       v[x0,y0]:=false;
29       for i:=1 to 4 do
30       begin
31         x:=x0+dx[i];
32         y:=y0+dy[i];
33          if (x<0) or (x>n) or (y<0) or (y>m) then continue;
34         if f[x,y,k]>f[x0,y0,k]+a[x,y] then
35         begin
36           f[x,y,k]:=f[x0,y0,k]+a[x,y];
37           pre[x,y,k]:=make(x0,y0,k);
38           if not v[x,y] then
39           begin
40             v[x,y]:=true;
41             inc(r);
42             q[r].x:=x; q[r].y:=y;
43           end;
44         end;
45       end;
46       inc(h);
47     end;
48   end;
49
50 procedure dfs(x,y,k:longint);
51   var m:node;
52   begin
53     v[x,y]:=true;
54     m:=pre[x,y,k];
55     if m.x=0 then exit;
56     dfs(m.x,m.y,m.k);
57     if (m.x=x) and (m.y=y) then dfs(m.x,m.y,k-m.k);
58   end;
59
60 begin
62   for i:=1 to n do
63     for j:=1 to m do
64       for k:=0 to 1024 do
65         f[i,j,k]:=inf;
66   for i:=1 to n do
67     for j:=1 to m do
68     begin
70       if a[i,j]=0 then
71       begin
72         f[i,j,1 shl t]:=0;
73         inc(t);
74       end;
75     end;
76   h:=1;
77   r:=0;
78   for k:=1 to 1 shl t-1 do
79   begin
80     for i:=1 to n do
81       for j:=1 to m do
82       begin
83         s:=k and (k-1);
84         while s<>0 do  //穷举子集
85         begin
86           if f[i,j,k]>f[i,j,s]+f[i,j,k-s]-a[i,j] then
87           begin
88             f[i,j,k]:=f[i,j,s]+f[i,j,k-s]-a[i,j];
89             pre[i,j,k]:=make(i,j,s); //记录从哪转移来的
90           end;
91           s:=k and (s-1);
92         end;
93         if f[i,j,k]<inf then
94         begin
95           v[i,j]:=true;
96           inc(r);
97           q[r].x:=i; q[r].y:=j;
98         end;
99       end;
100     spfa(k);
101     h:=1;
102     r:=0;
103   end;
104   for i:=1 to n do
105     for j:=1 to m do
106       if a[i,j]=0 then
107       begin
108         x:=i;
109         y:=j;
110         break;
111       end;
112
113   writeln(f[x,y,1 shl t-1]);
114   dfs(x,y,1 shl t-1);
115   for i:=1 to n do
116   begin
117     for j:=1 to m do
118       if a[i,j]=0 then write('x')
119       else if v[i,j] then write('o')
120       else write('_');
121     writeln;
122   end;
123 end.
View Code

posted on 2015-05-09 16:35  acphile  阅读(239)  评论(0编辑  收藏  举报