`
java-mans
  • 浏览: 11416781 次
文章分类
社区版块
存档分类
最新评论

POJ 4046 Sightseeing 最短路

 
阅读更多

题意就不再赘述了

黑书上308页例1是极其相似的题。。。。

思路也一样

枚举每个点作为吃饭的地点。

每次以枚举的这个点为起点做最短路,途中不能走比它贵的点。

每次求出最短路后要更新我们的查询答案。更新其实也就是一行的样子。

假设查询的两个点有个最优的方案,那么路径上有某点是吃饭的地点,那么从该点出发按刚才的方法一定能找到查询的那两个点。

据称本题卡常数,我最后用了3400ms 的样子。

那么尽量不要用stl的东西了。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#define eps 1e-5
#define MAXN 1005
#define MAXM 40005
#define INF 10000000000007LL
using namespace std;
struct EDGE
{
    int v, next, w;
}edge[MAXM];
int head[MAXN], e;
void init()
{
    memset(head, -1, sizeof(head));
    e = 0;
}
void add(int x, int y, int w)
{
    edge[e].v = y;
    edge[e].w = w;
    edge[e].next = head[x];
    head[x] = e++;
}
long long d[MAXN], ans[MAXM];
int a[MAXM], b[MAXM], val[MAXN];
int que[MAXM * 5], vis[MAXN];
int q, n, m;
void spfa(int src)
{
    for(int i = 0; i <= n; i++) d[i] = INF, vis[i] = 0;
    int h = 0, t = 0;
    vis[src] = 1;
    d[src] = 0;
    que[t++] = src;
    while(h < t)
    {
        int u = que[h++];
        vis[u] = 0;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].v;
            if(val[v] <= val[src] && d[u] + edge[i].w < d[v])
            {
                d[v] = d[u] + edge[i].w;
                if(!vis[v])
                {
                    vis[v] = 1;
                    que[t++] = v;
                }
            }
        }
    }
    for(int i = 1; i <= q; i++)
        if(d[a[i]] != INF && d[b[i]] != INF && ans[i] > d[a[i]] + d[b[i]] + val[src])
            ans[i] = d[a[i]] + d[b[i]] + val[src];
}
int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        if(!n && !m) break;
        init();
        int u, v, w;
        for(int i = 1; i <= n; i++) scanf("%d", &val[i]);
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            add(u, v, w), add(v, u, w);
        }
        scanf("%d", &q);
        for(int i = 1; i <= q; i++)
        {
            scanf("%d%d", &a[i], &b[i]);
            ans[i] = INF;
        }
        for(int i = 1; i <= n; i++) spfa(i);
        for(int i = 1; i <= q; i++)
        {
            if(ans[i] == INF) printf("-1\n");
            else printf("%lld\n", ans[i]);
        }
        puts("");
    }
    return 0;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics