gavanwanggw

导航

hdu1690Bus System--解题报告

题意:有一个公交系统的收费标准例如以下表:

然后问:给出 这些L1~4 & C1~4的值,然后 N个站。列出每一个站的X坐标。然后询问M次,问两个站台的最小花费
题解:那么这里非常明显是最短路问题。有一点的麻烦就在于建图,那么我们能够对于全部的点,用两个for循环。算出两两之间的距离。就能够得到花费是多少,同一时候建边。然后对于每次询问的点,我们就spfa一次就OK
<span style="font-size:14px;">#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>

using namespace std;

#define INF 0xffffffffffffff
#define MAX 105
#define LL __int64

int N,M;
LL L1,L2,L3,L4,C1,C2,C3,C4;
LL X[MAX];

struct Edge{
    int to,next;
    LL cost;
}edge[MAX*MAX];
int head[MAX],tol;

void add(int u,int v,LL cost)
{
    edge[tol].to = v;
    edge[tol].cost = cost;
    edge[tol].next = head[u];
    head[u] = tol++;
}

void del() //处理建边
{
    LL cost,dis;
    for(int i = 1; i <= N; i ++){
        for(int j = i+1; j <= N; j ++){
            if(X[i] > X[j]) dis = X[i]-X[j];
            else dis = X[j]-X[i];

            if(dis > L4) cost = INF;
            else if(dis > L3) cost = C4;
            else if(dis > L2) cost = C3;
            else if(dis > L1) cost = C2;
            else cost = C1;

            add(i,j,cost);
            add(j,i,cost);
        }
    }
}

LL dis[MAX];
bool flag[MAX];
LL spfa(int src,int D)
{
    for(int i = 1; i <= N; i ++) dis[i] = INF;
    memset(flag,false,sizeof(flag));
    dis[src] = 0;
    flag[src] = true;

    queue<int>q;
    q.push(src);

    while(!q.empty())
    {
        int u = q.front(); q.pop();
        flag[u] = false;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to; LL cost = edge[i].cost;
            if(cost + dis[u] < dis[v])
            {
                dis[v] = cost+dis[u];
                if(!flag[v])
                {
                    q.push(v);
                    flag[v] = true;
                }
            }
        }
    }
    return dis[D];
}

int main()
{
    int T;
    scanf("%d",&T);

    for(int cas = 1; cas <= T; cas ++)
    {
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&L1,&L2,&L3,&L4,&C1,&C2,&C3,&C4);
        scanf("%d%d",&N,&M);
        for(int i = 1; i <= N; i ++) scanf("%I64d",&X[i]);

        memset(head,-1,sizeof(head));
        tol = 0;

        del();

        printf("Case %d:\n",cas);
        int a,b;
        LL ans = 0;
        for(int i = 0; i < M; i ++)
        {
            scanf("%d%d",&a,&b);
            ans = spfa(a,b);
            if(ans >= INF)
               printf("Station %d and station %d are not attainable.\n",a,b);
            else
               printf("The minimum cost between station %d and station %d is %I64d.\n",a,b,ans);
        }
    }

    return 0;
}</span>
那么这里的话,还要注意的是 由于坐标值比較大,我们用 64位来保存

posted on 2017-04-14 09:11  gavanwanggw  阅读(108)  评论(0编辑  收藏  举报