658 - It's not a Bug, it's a Feature! (Dijkstra算法)

来源:互联网 发布:斗鱼主播唱歌软件 编辑:程序博客网 时间:2024/06/07 06:03

今天第一次系统的学习了一下最短路算法,开始刷第十一章,第一次写Dijkstra算法,出现了很多喜闻乐见的错误。。而且uva上样例很水,瓢虫也很水 ,坑了我好久。

首先是对于结点的处理,我们必须要维护一个二元组,一个表示结点一个表示当前结点最短路。   因为Dijkstra算法利用了优先队列来加速算法,所以需要定义小于运算符,一开始我直接将状态装进了优先队列,显然是不对的,因为优先队列的作用就是取出当前距离最短的结点。

其次,说说最短路算法蕴含的巧妙思想: 每次从当前所有还未标记的结点中选择一个距离最小的点,从这个点更新与之相连的所有结点 。重复此过程 。 

为什么这样做是正确的呢? 百度百科上有一个动态图可以帮助我们很好的理解这个过程 。传送门:点击打开链接

该题是一个很巧妙的最短路问题,需要我们把模型抽象出来,看清楚要解决的问题的实质是什么。

该题是复杂状态的最短路问题,需要将状态抽象出来当做结点 。 

将状态集合当做结点,将所花费的时间当做边的权值,两个“结点”是否相连取决于第一个字符串与该结点的关系! 真是好题 ~

另外一点,用动态规划进行状态转移时很重要的一点是不能转移到以前的状态,即状态图不是DAG,所以不能用记忆化搜索 。 

细节参见代码:

#include<bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 22;const int maxm = 105;int n,m,kase = 0,ok = 0 ,d[1<<maxn],done[1<<maxn];struct node{    int t;    char a[maxn],b[maxn];}pat[maxm];struct Node{    int bugs,dist;    bool operator < (const Node& v) const {        return dist > v.dist;    }};int dijkstra() {    priority_queue<Node> q;    for(int i=0;i<(1<<n);i++) { done[i] = 0; d[i] = INF; }    Node u; u.dist = 0; u.bugs = (1<<n)-1;    d[u.bugs] = 0;    q.push(u);    while(!q.empty()) {        Node u = q.top(); q.pop();        if(u.bugs == 0) return u.dist;        if(done[u.bugs]) continue;        done[u.bugs] = true;        for(int i=1;i<=m;i++) {            bool ok = true;            for(int j=0;j<n;j++) {  //检查该结点是否可以连一条边                if(pat[i].a[j] == '-' && u.bugs & (1<<j)) { ok = false; break; }                 if(pat[i].a[j] == '+' && !(u.bugs & (1<<j))) { ok = false; break; }            }            if(ok) {                Node v = u ;                for(int j=0;j<n;j++) { //更新找到下一个结点                    if(pat[i].b[j] == '-') {                         v.bugs &= ~(1<<j);                    }                    else if(pat[i].b[j] == '+') {                        v.bugs |= (1<<j);                    }                }                if(d[v.bugs] > u.dist + pat[i].t) {                    d[v.bugs] = u.dist + pat[i].t;                    v.dist = d[v.bugs];                    q.push(v);                }            }        }    }    return -1;}int main() {    while(~scanf("%d%d",&n,&m)) {        if( !n && !m ) return 0;        for(int i=1;i<=m;i++) {            scanf("%d%s%s",&pat[i].t,pat[i].a,pat[i].b);        }        int ans = dijkstra();        printf("Product %d\n",++kase);        if(ans < 0) printf("Bugs cannot be fixed.\n\n");        else printf("Fastest sequence takes %d seconds.\n\n",ans);    }    return 0;}


1 0
原创粉丝点击