题意:有一个公交系统的收费标准如下表:
然后问:给出 这些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位来保存