• UVA 658 状态压缩+隐式图+优先队列dijstla


    不可多得的好题目啊,我看了别人题解才做出来的,这种题目一看就会做的实在是大神啊,而且我看别人博客都看了好久才明白。。。还是对状态压缩不是很熟练,理解几个位运算用了好久时间。有些题目自己看着别人的题解做出来完全不是一个味,毕竟别人给你提供了思路,比如这道题,刚看题目,怎么就能转移到是用最短路搜索呢。。其次,好多注意事项这些自己想出来才真正是锻炼思维。否则总是踩着别人的脚印在行走

    还有就是不得不说一说UVA上的题目,又长又难懂。。。实在是弄得我好烦。

    说说这个题目,能够发现是个隐式图是第一个难点,然后怎么进行搜索就是关键了,状态压缩确实是个好东西,通过二进制来表示当前bug是否被修复,1 为bug,0为已修复,因此,初始状态就是n个1,因为补丁有诸多限制,有的需要某个bug已经被修复了才能运行该补丁,有些需要某些bug还在,每个bug分别用两个变量来分别记录需要哪些bug被修复,以及哪些bug需要存在,此外,补丁可以修补某个bug的同时又可能会产生新的bug,同样用两个变量来记录bug的消失和产生。

    用到的pair和优先队列,第一次用,还需要继续熟悉。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <vector>
    using namespace std;
    struct node
    {
        int value;
        int bp,bm,tp,tm;
    } patch[110];
    int vis[1<<20];
    bool flag;
    typedef pair<int , int> pill;
    struct cmp
    {
        bool operator()(const pill a,const pill b){
         return a.first>b.first;
        }
    };
    
    priority_queue<pill,vector<pill>,cmp> q;
    int nbug,npatch,vmin;
    void init()
    {
        flag=0;
        while (!q.empty())
          q.pop();
        memset(vis,0,sizeof vis);
        for (int i=0;i<=npatch;i++)
        {
            patch[i].bp=patch[i].bm=patch[i].tp=patch[i].tm=0;
        }
    }
    void dijstla()
    {
        q.push(make_pair(0,(1<<nbug)-1));
        while (!q.empty())
        {
            pill u=q.top();
            q.pop();
            //printf("%x
    ",u.second);
            if (u.second==0)
            {
                flag=1;
                vmin=u.first;
                return;
            }
            if (vis[u.second]) continue;
            vis[u.second]=1;
            for (int i=0;i<npatch;i++)
            {
                int t=u.second;
                if (((t&patch[i].bp)==patch[i].bp) && (((~t)&patch[i].bm)==patch[i].bm))
                {
                   t|=patch[i].tp;
                   t&=(~patch[i].tm);
                }
                q.push(make_pair(u.first+patch[i].value,t));
            }
        }
    }
    int main()
    {
        int i,j;
        char c1[25],c2[25];
        int cnt=0;
        while (scanf("%d%d",&nbug,&npatch))
        {
            if (!nbug && !npatch) break;
            init();
            for (i=0;i<npatch;i++)
            {
                scanf("%d%s%s",&patch[i].value,c1,c2);
                for (j=0;j<nbug;j++)
                {
                    if (c1[j]=='+') patch[i].bp=patch[i].bp|(1<<j);
                    if (c1[j]=='-') patch[i].bm=patch[i].bm|(1<<j);
                    if (c2[j]=='+') patch[i].tp=patch[i].tp|(1<<j);
                    if (c2[j]=='-') patch[i].tm=patch[i].tm|(1<<j);
                }
            }
            dijstla();
            printf("Product %d
    ",++cnt);
            if (!flag)
            {
                puts("Bugs cannot be fixed.");
            }
            else
            {
                printf("Fastest sequence takes %d seconds.
    ",vmin);
            }
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    JVMTIAgent
    Java 虚拟机编程接口JVMIT
    Java调试平台体系JPDA
    什么是缓存
    2019第49周日
    什么是你拥有的资本
    java里的static/final含义
    Java语言和JVM的使用说明书
    画图前端:mermaid。时序图/类图/甘特图/流程图/状态图/饼图。类似工具:Typora
    java通过下划线数字字面量增加可读性:10_00_00表示100000
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3516507.html
Copyright © 2020-2023  润新知