JZOJ_1321. 灯 (Standard IO)

Description

  贝希和她的闺密们在她们的牛棚中玩游戏。但是天不从人愿,突然,牛棚的电源跳闸了,所有的灯都被关闭了。贝希是一个很胆小的女生,在伸手不见拇指的无尽的黑暗中,她感到惊恐,痛苦与绝望。她希望您能够帮帮她,把所有的灯都给重新开起来!她才能继续快乐地跟她的闺密们继续玩游戏!
  牛棚中一共有N(1 <= N <= 35)盏灯,编号为1到N。这些灯被置于一个非常复杂的网络之中。有M(1 <= M <= 595)条很神奇的无向边,每条边连接两盏灯。
  每盏灯上面都带有一个开关。当按下某一盏灯的开关的时候,这盏灯本身,还有所有有边连向这盏灯的灯的状态都会被改变。状态改变指的是:当一盏灯是开着的时候,这盏灯被关掉;当一盏灯是关着的时候,这盏灯被打开。
  问最少要按下多少个开关,才能把所有的灯都给重新打开。
  数据保证至少有一种按开关的方案,使得所有的灯都被重新打开。
 

Input

  第一行:两个空格隔开的整数:N和M。
  第二到第M+1行:每一行有两个由空格隔开的整数,表示两盏灯被一条无向边连接在一起。没有一条边会出现两次。
 

Output

  第一行:一个单独的整数,表示要把所有的灯都打开时,最少需要按下的开关的数目。
 

Solution

     这题用折半搜索做,O(2N/2),不会TLE。

     有大佬说可以用高斯消元做。

 

代码

 

  1 const
  2   mo=1000009;
  3 var
  4   n,m,m1,m2,ans:longint;
  5   ha,b:array [0..mo] of int64;
  6   op,f:array [0..40] of int64;
  7   a:array [0..40,0..40] of longint;
  8   bo:array [0..40] of boolean;
  9 function min(o,p:longint):longint;
 10 begin
 11   if o<p then exit(o);
 12   exit(p);
 13 end;
 14 
 15 procedure init;
 16 var
 17   i,j,x,y:longint;
 18 begin
 19   op[0]:=1;
 20   for i:=1 to 36 do op[i]:=op[i-1]*2;
 21   readln(n,m);
 22   for i:=1 to m do
 23     begin
 24       readln(x,y);
 25       inc(a[x,0]); a[x,a[x,0]]:=y;
 26       inc(a[y,0]); a[y,a[y,0]]:=x;
 27     end;
 28   for i:=1 to n do
 29     begin
 30       f[i]:=op[i-1];
 31       for j:=1 to a[i,0] do
 32         f[i]:=f[i]+op[a[i,j]-1];
 33     end;
 34 end;
 35 
 36 function hash(x:int64):longint;
 37 var
 38   i:longint;
 39 begin
 40   i:=x mod mo;
 41   while (ha[i]<>0) and (ha[i]<>x) do
 42     i:=(i+1) mod mo;
 43   exit(i);
 44 end;
 45 
 46 procedure dfs1(x:longint);
 47 var
 48   num:int64;
 49   k,tk,i:longint;
 50 begin
 51   if x>m1 then
 52     begin
 53       num:=0; tk:=1;
 54       for i:=1 to m1 do
 55         if bo[i] then
 56           begin
 57             num:=num xor f[i];
 58             inc(tk);
 59           end;
 60       k:=hash(num);
 61       if ha[k]=0 then
 62         begin
 63           ha[k]:=num; b[k]:=tk;
 64         end else b[k]:=min(b[k],tk);
 65       exit;
 66     end;
 67   bo[x]:=true; dfs1(x+1);
 68   bo[x]:=false; dfs1(x+1);
 69 end;
 70 
 71 procedure dfs2(x:longint);
 72 var
 73   num:int64;
 74   k,tk,i:longint;
 75 begin
 76   if x>m2 then
 77     begin
 78       num:=0; tk:=-1;
 79       for i:=m1+1 to m2 do
 80         if bo[i] then
 81           begin
 82             num:=num xor f[i];
 83             inc(tk);
 84           end;
 85       k:=hash(op[n]-num-1);
 86       if ha[k]<>0 then
 87         ans:=min(ans,b[k]+tk);
 88       exit;
 89     end;
 90   bo[x]:=true; dfs2(x+1);
 91   bo[x]:=false; dfs2(x+1);
 92 end;
 93 
 94 begin
 95   init;
 96   m1:=min(18,n); m2:=n;
 97   ans:=maxlongint;
 98   dfs1(1);
 99   dfs2(m1+1);
100   write(ans);
101 end.

 

 

 

posted @ 2018-08-16 16:31  猪都哭了  阅读(145)  评论(0编辑  收藏  举报