码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1770 [Usaco2009 Nov]lights 燈 meet in the middle

时间:2018-08-14 20:02:12      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:tmp   ==   dig   cto   The   c++   for   高斯消元   cout   

题面

题目传送门

解法

题解里都是高斯消元然后dfs,蒟蒻表示不会

直接分两半dfs即可

时间复杂度:\(O(2^{\frac{n}{2}})\)

代码

#include <bits/stdc++.h>
#define LL long long
#define N 110
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
    x = 0; int f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();}
    while (isdigit(c)) x = x * 10 + c - ‘0‘, c = getchar(); x *= f;
}
int ans; LL s[N];
vector <int> e[N];
map <LL, int> h;
void dfs1(int x, int n, int sum, LL tmp) {
    if (x > n) {
        h[tmp] = sum;
        return;
    }
    dfs1(x + 1, n, sum + 1, tmp ^ s[x]);
    dfs1(x + 1, n, sum, tmp);
}
void dfs2(int x, int n, int sum, LL tmp) {
    if (x > n) {
        LL y = ((1ll << n) - 1) ^ tmp;
        if (h.count(y)) chkmin(ans, h[y] + sum);
        return;
    }
    dfs2(x + 1, n, sum + 1, tmp ^ s[x]);
    dfs2(x + 1, n, sum, tmp);
}
int main() {
    int n, m; read(n), read(m);
    for (int i = 1; i <= m; i++) {
        int x, y; read(x), read(y);
        s[x] |= 1ll << y - 1;
        s[y] |= 1ll << x - 1;
    }
    for (int i = 1; i <= n; i++) s[i] |= 1ll << i - 1;
    dfs1(1, n / 2, 0, 0);
    ans = INT_MAX; dfs2(n / 2 + 1, n, 0, 0);
    cout << ans << "\n";
    return 0;
}

bzoj 1770 [Usaco2009 Nov]lights 燈 meet in the middle

标签:tmp   ==   dig   cto   The   c++   for   高斯消元   cout   

原文地址:https://www.cnblogs.com/copperoxide/p/9476736.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!