题意:有一个公交系统的收费标准例如以下表:
然后问:给出 这些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: ",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. ",a,b); else printf("The minimum cost between station %d and station %d is %I64d. ",a,b,ans); } } return 0; }</span>那么这里的话,还要注意的是 由于坐标值比較大,我们用 64位来保存