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

hdu1818 It's not a Bug, It's a Feature!(隐式图最短路径Dijkstra)

时间:2015-08-12 21:42:48      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接


题目描述:补丁在修bug时,有时也会引入新的bug,假设有n(n<=20)个潜在的bug和m(m<=100)个补丁,每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug。第一个串表示打补丁之前的状态(‘-‘表示在该位置不存在bug,‘+‘表示该位置必须存在bug,0表示无所谓),第二个串表示打补丁之后的状态(‘-’表示不存在,‘+‘表示存在,0表示不变)。每个补丁都有一个执行时间,你的任务是用最少的时间把一个所有bug都存在的软件通过打补丁的方式变得没bug。一个补丁可以打多次。


解题思路:

首先思考动态规划是否可行?显然某个状态经过多次补丁修过之后可能会回到某一状态,并不是DAG,如果使用记忆化搜索会出现无限递归

正确的做法:把每个状态看成结点,状态转移看成边,转化成图论中的最短路径问题,然后使用Dijkstra算法求解。不过这道题和普通的最短路径问题不一样:节点很多,多达2^n个,而且很多状态根本遇不到,所以没有必要像前面那样把图存好。这里我们可以像隐式图搜索一样,对某个结点在搜索的过程中进行扩展(枚举所有的补丁)


代码:

#include <bitset>
#include <cstdio>
#include <iostream>
#include <queue>
#define MAXN 1100000
#define INF 1e9+7
using namespace std;
typedef bitset<20> bit;
struct patches{
    int nt;
    string from;
    string to;
    patches(int _nt,string _from,string _to):nt(_nt),from(_from),to(_to){}
}*pts[101];
struct node{
    int ct;
    bit bits;
    node(int _ct,bit _bits):ct(_ct),bits(_bits){}
    bool operator<(const node& b)const{
        return ct>b.ct;
    }
};
int n,m;
bit from;
int dis[MAXN];
bool check(bit bt1,string bt2){
    for(int i=0;i<n;++i){
        if(bt2[i]=='+'&&!(bt1.test(i)))
            return false;
        if(bt2[i]=='-'&&bt1.test(i))
            return false;
    }
    return true;
}
void change(bit& bt1,string bt2){
    for(int i=0;i<n;++i){
        if(bt2[i]=='+')
            bt1.set(i);
        else if(bt2[i]=='-')
            bt1.reset(i);
    }
}
void dijkstar(){
    priority_queue<node> Q;
    while(!Q.empty()) Q.pop();

    int tsize=from.to_ulong();
    for(int i=0;i<=tsize;i++)
        dis[i]=INF;

    dis[from.to_ulong()]=0;
    Q.push(node(0,from));
    while(!Q.empty()){
        node tmp=Q.top();Q.pop();
        bit tbit(tmp.bits);
        if(tbit.to_ulong()==0)
            return;
        if(tmp.ct>dis[tbit.to_ulong()])
            continue;
        for(int i=0;i<m;i++){
            if(check(tbit,pts[i]->from)){
                bit tt(tbit);
                change(tt,pts[i]->to);
                int tt1=tbit.to_ulong();
                int tt2=tt.to_ulong();
                if(tt1<INF&&dis[tt2]>(dis[tt1]+pts[i]->nt)){
                    dis[tt2]=dis[tt1]+pts[i]->nt;
                    Q.push(node(dis[tt2],tt));
                }
            }
        }
    }
}
int main(){
    int cas=1;
    while((cin>>n>>m)&&(n!=0||m!=0)){
        string a,b;
        int tt;
        for(int i=0;i<m;++i){
            cin>>tt>>a>>b;
            pts[i]=new patches(tt,a,b);
        }
        from.reset();
        for(int i=0;i<n;i++)
            from.set(i);
        dijkstar();
        printf("Product %d\n",cas);
        if(dis[0]<INF)
            printf("Fastest sequence takes %d seconds.\n",dis[0]);
        else
            printf("Bugs cannot be fixed.\n");
        cas++;
        printf("\n");
    }
    return 0;
}


收获:

1、隐式图上的Djkstra

2、bitset的使用


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu1818 It's not a Bug, It's a Feature!(隐式图最短路径Dijkstra)

标签:

原文地址:http://blog.csdn.net/mengxingyuanlove/article/details/47450825

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