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位来保存
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值