zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    webapi 获取json数据
    js的匿名函数与自定义函数
    深入理解计算机系统 第八章 异常控制流(2)
    深入理解计算机系统 第八章 异常控制流(1)
    深入理解计算机系统 第三章 程序的机器级表示(2)
    深入理解计算机系统 第三章 程序的机器级表示(1)
    深入理解计算机系统 第二章 信息的表示和处理(2)
    深入理解计算机系统 第二章 信息的表示和处理(1)
    深入理解计算机系统第一章,计算机系统漫游
    Leetcode练习(Python):第292题:Nim 游戏:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9488141.html
Copyright © 2011-2022 走看看