POJ 1062 昂贵的聘礼(枚举+dijkstra算法)

来源:互联网 发布:淘宝2千100cm实体娃娃 编辑:程序博客网 时间:2024/06/03 09:17

题目大意:

一个有向带权图,求源点到其他顶点的最短路径和该顶点值的和的最小值,典型的单元最短路径问题。不过每个顶点都有一个等级,源点到任意一个顶点最短路径上的任意两个顶点(包括源点和该顶点)的等级差不能超过给定的值。

解题思路:

我做这道题的经历:

1、题意理解错误,错认为只要满足相邻的结点的等级差在给定范围内就可以。

2、在dijkstra算法中记录每个结点的父亲结点,在讨论一个结点时,根据父亲结点不断往上遍历直到源点,如果该结点与往上遍历的所有父亲结点的等级差都在指定范围内,则更新该结点。(这用方法对有的路径不能考虑进去)

3、深搜,深搜算法写的不好,出现MLE

4、枚举一定范围内的点,dijkstra算法中只考虑在枚举范围内的顶点。(过题)

代码:

#include <cstdio>#include <cstring>#define M 125const int INF = (1<<30)-1;int m, n;int p, l, x, t, v;int value[M], charge[M][M];int layer[M], low, high;int vis[M], lowcost[M], path[M];void dijkstra(int beg) {    int i, j, minc;    memset(vis, 0, sizeof(vis));    vis[beg] = 1;    for(i=0; i<n; i++) {        //在初始化lowcost[]数组的时候要判断其等级是否在指定范围,在这WA了多次        if(layer[i]>=low && layer[i]<=high)            lowcost[i] = charge[beg][i];        else lowcost[i] = INF;    }    lowcost[beg] = 0;    int pre = beg;    for(int i=1; i<n; i++) {        minc = INF;        for(j=0; j<n; j++) {            if(vis[j] == 0 && lowcost[pre]+charge[pre][j]<lowcost[j] &&               layer[j] >=low && layer[j] <= high) {    //值考虑在枚举范围内的点                lowcost[j] = lowcost[pre] + charge[pre][j];            }        }        for(j=0; j<n; j++) {            if(vis[j] == 0 && lowcost[j] < minc && layer[j]>=low && layer[j]<=high) {  //同样只需要考虑在                minc = lowcost[j]; pre = j;                                            //枚举范围之内的点            }        }        vis[pre] = 1;    }}void init() {    for(int i=0; i<n; i++) {        for(int j=0; j<n; j++) {            if(i == j) charge[i][j] = 0;            else                charge[i][j] = INF;        }    }}int main() {    while(~scanf("%d%d", &m, &n)) {        init();        for(int i=0; i<n; i++) {            scanf("%d%d%d", &p, &l, &x);            value[i] = p; layer[i] = l;            for(int j=0; j<x; j++) {                scanf("%d%d", &t, &v);                charge[i][t-1] = v;            }        }        int ans = INF;        for(low = layer[0]-m; low<=layer[0]; low++) {  //枚举等级范围,对于每个范围,用dijkstra算法                high = low + m;                        //求出最优值。                dijkstra(0);                for(int i=0; i<n; i++) {                    if(lowcost[i] + value[i] < ans) {                        ans = lowcost[i] + value[i];                    }                }        }        printf("%d\n", ans);    }    return 0;}



0 0
原创粉丝点击