zoukankan      html  css  js  c++  java
  • 状态转移的最短路 隐式图搜索 UVA 658

    紫书365

    题目大意:给你n个全都是bug的东西,然后每次可以修复,给你修复前后的状态,问最后如果能把bug全都修复,最少需要多少时间。

    思路:从最初状态开始,然后枚举bug即可。

    表示priority里面的bool operator和单纯的sort的定义的大小于号是不一样的啊,如果你想用sort来计算struct从小到大的的话是这样的

    struct Node{
        int bugs, dist;
        bool operator < (const Node &a) const{
            return dist < a.dist;
        }
        Node(int b = 0, int d = 0): bugs(b), dist(d){}
    };
    View Code

    而优先队列是这样的

    struct Node{
        int bugs, dist;
        bool operator < (const Node &a) const{
            return dist > a.dist;
        }
        Node(int b = 0, int d = 0): bugs(b), dist(d){}
    };
    View Code

    区分一下大小于号就好了

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    const int inf = 0x3f3f3f3f;
    const int maxn = (1 << 20) + 5;
    const int maxm = 100 + 5;
    int n, m;
    int t[maxm], d[maxn];
    bool vis[maxn];
    char b[maxm][30], e[maxm][30];
    struct Node{
        int bugs, dist;
        bool operator < (const Node &a) const{
            return dist > a.dist;
        }
        Node(int b = 0, int d = 0): bugs(b), dist(d){}
    };
    
    int solve(){
        memset(vis, false, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        priority_queue<Node> que;
        int tmp = (1 << n) - 1;
        que.push(Node(tmp, 0));
        d[tmp] = 0; vis[tmp] = 1;
        while (!que.empty()){
            Node u = que.top(); que.pop();
            if (u.bugs == 0) return u.dist;
            for (int i = 0; i < m; i++){
                int from = u.bugs;
                bool flag = false;
                for (int j = 0; j < n; j++){
                    if (b[i][j] == '-' && (from & (1 << j))) {flag = true; break;}
                    if (b[i][j] == '+' && !(from & (1 << j))) {flag = true; break;}
                }
                if (flag) continue;
                int to = from;
                for (int j = 0; j < n; j++){
                    if (e[i][j] == '-' && (from & (1 << j))) to ^= 1 << j;
                    if (e[i][j] == '+') to |= 1 << j;
                }
                if (d[to] > d[from] + t[i] && !vis[to]){
                    d[to] = d[from] + t[i];
                    vis[to] = false;
                    que.push(Node(to, d[to]));
                }
            }
        }
        return -1;
    }
    
    int main(){
        int kase = 0;
        while (scanf("%d%d", &n, &m) && n){
            for (int i = 0; i < m; i++){
                scanf("%d", t + i);
                scanf("%s%s", b[i], e[i]);
            }
            printf("Product %d
    ", ++kase);
            int ans = solve();
            if (ans < 0) printf("Bugs cannot be fixed.
    ");
            else printf("Fastest sequence takes %d seconds.
    ", ans);
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    本地化中文示例代码需求调查
    微软一站式示例代码库下载过热导致下载计数器溢出bug
    中文版示例代码浏览器for Windows 8
    Tips of the Week for Microsoft Products
    [leetcode] Longest Substring Without Repeating Characters
    [leetcode] Add Two Numbers *
    树的直径 图的直径
    解题笔记(2)——部分面试题解题思路 [转]
    两个容积互质的水杯可倒出任意从1到容积和的水量
    latex中括号大小控制 [转]
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5878112.html
Copyright © 2011-2022 走看看