zoukankan      html  css  js  c++  java
  • BZOJ2595:[WC2008]游览计划

    Description

    Input

    第一行有两个整数,N和 M,描述方块的数目。 
    接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点;
    否则表示控制该方块至少需要的志愿者数目。 相邻的整数用 (若干个) 空格隔开,
    行首行末也可能有多余的空格。

    Output

    由 N + 1行组成。第一行为一个整数,表示你所给出的方案
    中安排的志愿者总数目。 
    接下来 N行,每行M 个字符,描述方案中相应方块的情况: 
    z  ‘_’(下划线)表示该方块没有安排志愿者; 
    z  ‘o’(小写英文字母o)表示该方块安排了志愿者; 
    z  ‘x’(小写英文字母x)表示该方块是一个景点; 
    注:请注意输出格式要求,如果缺少某一行或者某一行的字符数目和要求不
    一致(任何一行中,多余的空格都不允许出现) ,都可能导致该测试点不得分。

    Sample Input

    4 4
    0 1 1 0
    2 5 5 1
    1 5 5 1
    0 1 1 0

    Sample Output

    6
    xoox
    ___o
    ___o
    xoox

    HINT

     对于100%的数据,N,M,K≤10,其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内

    题解:

    裸裸的斯坦纳树,只是多了要求具体方案。

    将需要联通的景点是否在联通块中压缩为状态k。F[i,k]表示已i点为中心的联通块,包含的景点为状态k,所需要的最小费用。

    对于相邻的点i,j,可进行这样的转移:F[i,x]+F[j,y]——>F[i,x xor y]与F[j,x xor y]。对此进行spfa,记录其是由哪两个情况转移来的。

    为了减少复杂度,转移时保证x and y=0

    见证奇迹:

    (其实有种更优的DP写法,外加PASCAL在BZOJ中不享有明显的O2优化)

    代码:

     1 const
     2   fx:array[0..3]of longint=(-1,0,1,0);
     3   fy:array[0..3]of longint=(0,-1,0,1);
     4 var
     5   i,j,k:longint;
     6   n,m,ans1,ans2,cnt,s,e,fro1,fro2,to1,to2,pos:longint;
     7   map,map2:array[0..10,0..10]of longint;
     8   a:array[0..10,0..10,0..1024,0..3]of longint;
     9   bo:array[0..10,0..10,0..1024]of longint;
    10   f:array[0..1000001,1..3]of longint;
    11 procedure ss(x,y,z:longint);
    12 begin
    13   map2[x,y]:=1;
    14   if(a[x,y,z,1]=0)or(a[x,y,z,2]=0)then exit;
    15   ss(x,y,a[x,y,z,3]);
    16   ss(a[x,y,z,1],a[x,y,z,2],z xor a[x,y,z,3]);
    17 end;
    18 procedure wh(x,y:longint);
    19 begin
    20   if x>cnt then
    21   begin
    22     if a[fro1,fro2,pos,0]+a[to1,to2,y,0]<a[to1,to2,pos or y,0] then
    23     begin
    24       a[to1,to2,pos or y,0]:=a[fro1,fro2,pos,0]+a[to1,to2,y,0];
    25       a[to1,to2,pos or y,1]:=fro1; a[to1,to2,pos or y,2]:=fro2;
    26       a[to1,to2,pos or y,3]:=y;
    27       if bo[to1,to2,pos or y]=0 then
    28       begin
    29         bo[to1,to2,pos or y]:=1;
    30         inc(e); if e=1000001 then e:=1;
    31         f[e,1]:=to1; f[e,2]:=to2; f[e,3]:=pos or y;
    32       end;
    33     end;
    34     if a[fro1,fro2,pos,0]+a[to1,to2,y,0]<a[fro1,fro2,pos or y,0] then
    35     begin
    36       a[fro1,fro2,pos or y,0]:=a[fro1,fro2,pos,0]+a[to1,to2,y,0];
    37       a[fro1,fro2,pos or y,1]:=to1; a[fro1,fro2,pos or y,2]:=to2;
    38       a[fro1,fro2,pos or y,3]:=pos;
    39       if bo[fro1,fro2,pos or y]=0 then
    40       begin
    41         bo[fro1,fro2,pos or y]:=1;
    42         inc(e); if e=1000001 then e:=1;
    43         f[e,1]:=fro1; f[e,2]:=fro2; f[e,3]:=pos or y;
    44       end;
    45     end;
    46     exit;
    47   end;
    48   if pos and(1 shl(x-1))=0 then
    49   wh(x+1,y or(1 shl(x-1)));
    50   wh(x+1,y);
    51 end;
    52 begin
    53   readln(n,m);
    54   for i:=1 to n do
    55   for j:=1 to m do
    56   for k:=0 to 1023 do a[i,j,k,0]:=maxlongint div 2;
    57   for i:=1 to n do
    58   for j:=1 to m do
    59   begin
    60     read(map[i,j]);
    61     if map[i,j]=0 then
    62     begin
    63       inc(e); inc(cnt); f[e,1]:=i; f[e,2]:=j; f[e,3]:=1 shl(cnt-1);
    64       a[i,j,f[e,3],0]:=0; bo[i,j,f[e,3]]:=1;
    65     end else
    66     begin
    67       inc(e); f[e,1]:=i; f[e,2]:=j; f[e,3]:=0;
    68       a[i,j,0,0]:=map[i,j]; bo[i,j,0]:=1;
    69     end;
    70   end;
    71   a[0,0,(1 shl cnt)-1,0]:=maxlongint;
    72   while s<>e do
    73   begin
    74     inc(s); if s=1000001 then s:=1;
    75     fro1:=f[s,1]; fro2:=f[s,2]; pos:=f[s,3];
    76     if(pos=(1 shl cnt)-1)and(a[fro1,fro2,pos,0]<a[ans1,ans2,pos,0])
    77     then begin ans1:=fro1; ans2:=fro2; end;
    78     bo[fro1,fro2,pos]:=0;
    79     for i:=0 to 3 do
    80     if(fro1+fx[i]>=1)and(fro1+fx[i]<=n)and(fro2+fy[i]>=1)and(fro2+fy[i]<=m)
    81     then begin
    82       to1:=fro1+fx[i]; to2:=fro2+fy[i];
    83       wh(1,0);
    84     end;
    85   end;
    86   writeln(a[ans1,ans2,(1 shl cnt)-1,0]);
    87   ss(ans1,ans2,(1 shl cnt)-1);
    88   for i:=1 to n do
    89   begin
    90     for j:=1 to m do
    91     begin
    92       if map[i,j]=0 then write('x')
    93       else if map2[i,j]=1 then write('o')
    94       else write('_');
    95     end;
    96     writeln;
    97   end;
    98 end.
    View Code
  • 相关阅读:
    Masonry介绍与使用实践:快速上手Autolayout
    OC文件大小的计算方法,多用于清理缓存
    OC接收数据时毫秒转date时间最简略方法
    使用OC语言编写两个超大数相乘或相加的算法的思路和超大正整数相乘的代码
    简述AFN(AFNetWorking 2.X)的实现分析和简单使用【转】
    iOS开发中xib和Storyboard中需要注意的事项
    如何将UISearchBar上"Cancel"按钮改为”取消“?
    iOS开发中关于本地数据中SQLite数据库常用的SQL语句
    UItableViewCell上的button点击无响应的办法
    UIScrollView的几个要点总结
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6255152.html
Copyright © 2011-2022 走看看