zoukankan      html  css  js  c++  java
  • JZOJ 1321. 灯

    Description

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

    Input

      第一行:两个空格隔开的整数:N和M。

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

    Output

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

    Sample Input

    5 6
    1 2
    1 3
    4 2
    3 4
    2 5
    5 3
    

    Sample Output

    3
     
    做法:高斯消元解异或方程组,或折半搜索都可以过啦。
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #define LL long long
     6 using namespace std;
     7 LL m[60][60];
     8 int n, M, b[60], ans, Ans[60];
     9 
    10 void Init()
    11 {
    12     scanf("%d%d", &n, &M);
    13     for (int i = 1; i <= n; i++)
    14             m[i][i] = 1, b[i] = 1;
    15     for (int i = 1; i <= M; i++)
    16     {
    17         int u, v;
    18         scanf("%d%d", &u, &v);
    19         m[u][v] = 1;
    20         m[v][u] = 1;
    21     }
    22 }
    23 
    24 void Dfs(int dep, int count)
    25 {
    26     if (count >= ans)    return;
    27     if (dep == 0)
    28     {
    29         if (count < ans)    ans = count;
    30         return;
    31     }
    32     if (m[dep][dep])
    33     {
    34         bool now = b[dep];
    35         for (int i = dep + 1; i <= n; i++)
    36             if (m[dep][i])    now ^= Ans[i];
    37         Ans[dep] = now;
    38         if (Ans[dep])    Dfs(dep - 1, count + 1);
    39         else Dfs(dep - 1, count);
    40     }
    41     else
    42     {
    43         Ans[dep] = 0;    Dfs(dep - 1, count);
    44         Ans[dep] = 1;    Dfs(dep - 1, count + 1);
    45         Ans[dep] = 0;
    46     }
    47 }
    48 
    49 void Swap(int l, int r)
    50 {
    51     for (int i = 1; i <= n; i++)
    52         swap(m[l][i], m[r][i]);
    53     swap(b[l], b[r]);
    54 }
    55 
    56 void Xor(int l, int r)
    57 {
    58     for (int i = 1; i <= n; i++)
    59         m[l][i] ^= m[r][i];
    60     b[l] ^= b[r];
    61 }
    62 
    63 void Work()
    64 {
    65     for (int k = 1; k <= n; k++)
    66     {
    67         bool flag = 0;
    68         for (int i = k; i <= n; i++)
    69             if (m[i][k])
    70             {
    71                 flag = 1;
    72                 Swap(i, k);
    73                 break;
    74             }
    75         if (flag == 0)    continue;
    76         for (int i = k + 1; i <= n; i++)
    77             if (m[i][k])    Xor(i, k);
    78     }
    79 }
    80 
    81 int main()
    82 {
    83     Init();
    84     Work();
    85     ans = 10000000;
    86     Dfs(n, 0);
    87     printf("%d", ans);
    88 }
    高斯消元
     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define N 40
     5 #define M 100007
     6 #define LL long long
     7 using namespace std;
     8 int n, m, tot, g[M + 1], ans = M;
     9 LL h[M + 1], Ans, a[N], S[40];
    10 
    11 void Pre_work()
    12 {
    13     S[0] = 1;
    14     for (int i = 1; i <= 39; i++)    S[i] = S[i - 1] * 2;
    15 }
    16 
    17 void Init()
    18 {
    19     Pre_work();
    20     scanf("%d%d", &n, &m);
    21     int u, v;
    22     for (int i = 1; i <= n; i++)
    23         a[i] |= S[i];
    24     for (int i = 1; i <= m; i++)
    25     {
    26         scanf("%d%d", &u, &v);
    27         a[u] |= S[v];
    28         a[v] |= S[u];
    29     }    
    30     Ans = S[n + 1] - 2;    
    31 }
    32 
    33 int Hash(LL x)
    34 {
    35     int p =    x % M;
    36     for (; h[p] != 0 && h[p] != x; p = (p + 1) % M);
    37     return p; 
    38 }
    39 
    40 void Dfs(int dep, LL num, int step)
    41 {
    42     if (dep > tot)
    43     {
    44         if (num == Ans) ans = min(ans, step);
    45         int site = Hash(num);
    46         if (!h[site])    h[site] = num, g[site] = step;
    47         else g[site] = g[site] < step ? g[site] : step;
    48         return;
    49     }
    50     Dfs(dep + 1, num ^ a[dep], step + 1);
    51     Dfs(dep + 1, num, step);
    52 }
    53 
    54 void dfs(int dep, LL num, int step)
    55 {
    56     if (dep > n)
    57     {
    58         if (num == Ans) ans = min(ans, step);
    59         LL p = Ans ^ num;
    60         int site = Hash(p);
    61         if (h[site])    ans = min(ans, g[site] + step);
    62         return;
    63     }
    64     dfs(dep + 1, num ^ a[dep], step + 1);
    65     dfs(dep + 1, num, step);
    66 }
    67 
    68 int main()
    69 {
    70     Init();
    71     tot = n / 2;
    72     Dfs(1, 0, 0);
    73     dfs(tot + 1, 0, 0);
    74     printf("%d", ans);
    75 }
    折半搜索
  • 相关阅读:
    struts2的execAndWait拦截器
    听说百度网盘可以这样下载文件
    文件下载
    struts2文件上传
    注解实现struts2零配置
    struts2.properties
    拦截器
    curl+个人证书(又叫客户端证书)访问https站点
    Wireshark入门与进阶系列(一)
    Wireshark入门与进阶系列(二)
  • 原文地址:https://www.cnblogs.com/traveller-ly/p/9514444.html
Copyright © 2011-2022 走看看