POJ 4046 Sightseeing 解题报告

来源:互联网 发布:数据恢复精灵破解 编辑:程序博客网 时间:2024/04/30 09:44

题目


题意:

有一个图,节点为餐厅。道路边权为花费,餐厅有有花费,从某个点出发到某个点时,会选择花费最高度餐厅来消费。现在有Q个游览计划,对每个计划给出最小花费。

解法:

将餐厅按花费排序,然后依次做SPFA,表示以此餐厅为路上最高花费的餐厅。所以SPFA的时候更高价格的餐厅就不扩展。

Time:469msMemory:47836KBLength:3327B#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <map>#include <queue>#include <set>#include <sstream>#define DBLE 1e-8#define PI 3.1415926535898#define INF (100000000000000LL)#define MAXM 40010#define MAXN 1010#define MP(x,y) (make_pair((x),(y)))#define FI first#define SE secondusing namespace std;int nw[MAXN];int he[MAXN],to[MAXM],nex[MAXM],len[MAXM],top;long long dis[MAXN],ans[MAXM];//set<pair<long long,int> > se;int n,m, Q;bool vis[MAXN];int qa[20010], qb[20010];void add(int a,int b,int c){    nex[top]=he[a];    to[top]=b;    len[top]=c;    he[a]=top++;}int q[1000005];void spfa(int h){    q[1]=h;    int head=1, tail=1;    for (int i=1; i<=n; i++)    {            vis[i]=0;            dis[i]=INF;    }    dis[h]=0;    while (head<=tail)    {            int u=q[head++];            vis[u]=0;            for (int i=he[u]; i!=-1; i=nex[i])            {                    int v=to[i];                    if (nw[v]>nw[h]) continue;                    if (dis[v]>dis[u]+len[i])                    {                            dis[v]=dis[u]+len[i];                            if (!vis[v])                            {                                    vis[v]=1;                                    q[++tail]=v;                            }                    }            }    }    for (int i=1; i<=Q; i++)    {            int u=qa[i], v=qb[i];            if (dis[u]<INF && dis[v]<INF )                ans[i]=min(ans[i], dis[u]+dis[v]+nw[h]);    }}int main(){    //freopen("J:\\MyDocument\\Code\\input.txt","r",stdin);    while(scanf("%d%d",&n,&m)&&(n||m))    {        memset(he,-1,sizeof(he));        top=0;        for(int i=1;i<=n;++i)            scanf("%d",&nw[i]);        int a,b,c;        for(int i=0;i<m;++i)            scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,c);        scanf("%d",&Q);        for (int i=1; i<=Q; i++)        {                scanf("%d %d", &qa[i], &qb[i]);                ans[i]=INF;        }        for(int i=1;i<=n;++i)            spfa(i);        for (int i=1; i<=Q; i++)        {                if (ans[i]>=INF) ans[i]=-1;            printf("%I64d\n", ans[i]);        }        printf("\n");    }    return 0;}