zoukankan      html  css  js  c++  java
  • luogu2761 软件补丁问题 状态压缩最短路径

    关键词:状态压缩 最短路径

    想不出快速办法,就先考虑考虑暴力。枚举每一种错误分布的情况,然后通过可用的补丁转化为另多种情况,这些情况又转化为更多种情况……我们可以用图来表示这种关系!

    状态压缩:每个错误的状态可以压缩在一个整数里。

    最短路径:如果一个状态可以用补丁变为另一种状态,则两个状态间连一条边,权值为补丁所需时间。

    注意:二进制运算符,如&,|等,优先级比==低。所以有二进制运算时,等号左边记得要加括号。

    #include <cstdio>
    #include <cstring>
    #include <cassert>
    #include <iostream>
    #include <queue>
    #include <vector>
    using namespace std;
    
    #define LOOP(i, n) for(int i=0; i<n; i++)
    const int MAX_STATE = 1 << 21, INF = 0x3f3f3f3f, MAX_BUG = 25, MAX_PATCH = 110;
    int TotBug, TotPatch;
    int HaveBug[MAX_PATCH], Normal[MAX_PATCH], Repair[MAX_PATCH], Add[MAX_PATCH];
    int W[MAX_PATCH];
    
    struct Node;
    struct Edge;
    
    struct Node
    {
        Edge *Head;
        int Dist, State;
        bool Inq;
        Node() :Dist(INF){}
    }_nodes[MAX_STATE];struct Edge
    {
        Node *To;
        Edge *Next;
        int Weight;
        Edge(Node *to, Edge *next, int weight)
            :To(to),Next(next),Weight(weight){}
    };
    vector<Edge*> _edges;
    
    void AddEdge(int uId, int vId, int weight)
    {
        Node *from = uId + _nodes, *to = vId + _nodes;
        from->State = uId;
        to->State = vId;
        Edge *e = new Edge(to,from->Head,weight);
        _edges.push_back(e);
        from->Head = e;
    }
    
    void Build(Node *cur)
    {
        LOOP(patch, TotPatch)
        {
            if (((cur->State & HaveBug[patch]) == HaveBug[patch]) && ((~cur->State) & Normal[patch]) == Normal[patch])
            {
                int newState = ((~Repair[patch])&cur->State) | Add[patch];
                if (cur->State != newState)
                    AddEdge(cur->State, ((~Repair[patch])&cur->State) | Add[patch], W[patch]);
            }
        }
    }
    
    void SPFA()
    {
        static queue<Node*> q;
        int curState = (1 << TotBug) - 1;
        Node *cur = curState + _nodes;
        cur->State = curState;
        cur->Dist = 0;
        Build(cur);
        cur->Inq = true;
        q.push(cur);
        while (!q.empty())
        {
            cur = q.front();
            q.pop();
            if (cur->Inq)
                cur->Inq = false;
            for (Edge *e = cur->Head; e; e = e->Next)
            {
                if (cur->Dist + e->Weight < e->To->Dist)
                {
                    if (e->To->Dist == INF)
                        Build(e->To);
                    e->To->Dist = cur->Dist + e->Weight;    
                    if (!e->To->Inq)
                    {
                        e->To->Inq = true;
                        q.push(e->To);
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d", &TotBug, &TotPatch);
        char b[100], f[100];
        LOOP(patch, TotPatch)
        {
            scanf("%d %s %s", &W[patch], b, f);
            LOOP(bug, TotBug)
            {
                if (b[bug] == '+')
                    HaveBug[patch] |= (1 << bug);
                else if (b[bug] == '-')
                    Normal[patch] |= (1 << bug);
                if (f[bug] == '+')
                    Add[patch] |= (1 << bug);
                else if (f[bug] == '-')
                    Repair[patch] |= (1 << bug);
            }
        }
        SPFA();
        printf("%d
    ", _nodes[0].Dist == INF ? 0 : _nodes[0].Dist);
        return 0;
    }
  • 相关阅读:
    WebApi 安全认证
    Autofac 学习
    autofac实现批量注入
    Autofac -入门练习
    Struts2 Namespace_命名空间
    Deployment failure on Tomcat 6.x. Could not copy all resources
    chm 已取消到该网页的导航 或者 无法显示网页 的问题
    GPT 分区详解
    mount 中文手册
    rpm 中文手册
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8447621.html
Copyright © 2011-2022 走看看