加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 1724 A* 限制条件最短路

(2010-08-05 09:49:26)
标签:

poj

pku

1724

a

限制条件最短路

it

分类: 图论

题目描述:

给你一个图,每条边有长度l和花费c两个信息。

求从1~n的一条路,在总花费不超过k的情况下最短路是多少。

解题报告:

A*,用dij算法。

原点入优先队。

while(堆不空)

    取出堆顶(按路径长度排序,长度相同按花费排序,都是取最小的)

    如果堆顶是第n号节点,直接返回长度答案。

    否则,遍历堆顶的每条边。

        对于每条边,求出堆顶节点到边尾节点的花费和长度。

        如果花费在限制以内,就入队。

堆空了,还没找到答案,返回-1,不成功。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
#define size 120
struct edge{int from, to, v1, v2, next;} e[20000];
struct node
{
    int id, v1, v2;
    friend bool operator < (const node a, const node b)
    {
        if (a.v1 == b.v1) return a.v2 > b.v2;
        return a.v1 > b.v1;
    }
};
int v[size], d[size], cnt, k, n, r;
void insert(int from, int to, int v1, int v2)
{
    e[cnt].from = from, e[cnt].to = to, e[cnt].v1 = v1, e[cnt].v2 = v2;
    e[cnt].next = v[from]; v[from] = cnt++;
}
int dij()
{
    memset(d, -1, sizeof(d));
    priority_queue<node> que;
    node ne = {1, 0, 0};
    que.push(ne);
    while(!que.empty())
    {
        ne = que.top(); que.pop();
        d[ne.id] = ne.v1;
        if (ne.id == n) return d[n];
        int id = v[ne.id];
        while(id != -1)
        {
            node tmp = {e[id].to, ne.v1 + e[id].v1, ne.v2 + e[id].v2};
            if (tmp.v2 <= k) que.push(tmp);
            id = e[id].next;
        }
    }
    return -1;
}
int main()
{
    scanf("%d%d%d", &k, &n, &r);
    memset(v, -1, sizeof(v)); cnt = 0;
    for(int i = 0; i < r; i++)
    {
        int a, b ,c, d;
        scanf("%d%d%d%d", &a, &b, &c, &d);
        insert(a, b, c, d);
    }
    printf("%d\n", dij());
    return 0;
}

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有