【SPFA】火车票

    EkaterinburgSverdlovsk的火车线路上有若干个站点。这条线路可以近似的表示为一条线段,火车站就是线段上的点。线路始于Ekaterinburg,终于SverdlovskEkaterinburg被标号为1Sverdlovsk被标号为n。(n为整条线路上的站点数)

   线路上的任意两个站点间的直达票价是由它们间的距离决定的,票价根据以下规则制定:  

X为两站的距离  价格

    0<X<=L1    C1

    L1<X<=L2  C2

    L2<X<=L3  C3

    如果两站的间距超过L3,则无直达车票。所以有时可能有必要买多张票,通过转车的方式,从一个站到达另一个站。

    例如,在上面的图中,有7个站点。2号站点到6号站点的距离超过L3,不能买直达票。存在若干种中转的方法,其中的一种是买两张票:先花费C2从2号站到达3号站,然后花费C3从3号站到6号站,一种花费C2+C3。

    你的任务是,找出一种最经济的中转方案。

    输入

    从文本文件railway.in中读入数据。

    第一行6个整数L1, L2, L3, C1, C2, C3(1<=L1<l2<l3<=10^9, 1<="C1<C2<C3<=10^9),中间用空格分隔。"
    第二行一个整数n(2<=n<=100),表示线路上的车站数。
    第三行两个整数s和t,分别是起点和终点的编号。注意:s不一定小于t。
    以下的n-1行,按据Ekaterinburg远近,每行描述了一个车站的位置。它包含一个整数,表示该车站距Ekaterinburg的距离。

    任意两个车站的距离不超过10^9,任意两个相邻的车站的距离不超过L3。

    输出

    一个整数,表示从给定的一个站到给定的另一个站的最小花费。

  【样例输入】

3 6 8 20 30 40
7
2 6
3
7
8
13
15
23

  【样例输出】

70
     水题,按照题目要求建边即可。
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int l1,l2,l3,c1,c2,c3,s,t;
int h[105],d[105],cnt;
int a[105],n;
queue<int> q;
bool vis[105];
struct que
{
	int to,next,v;
}w[20005];
void add(int x,int y,int z)
{
	cnt++;
	w[cnt].to=y;
	w[cnt].v=z;
	w[cnt].next=h[x];
	h[x]=cnt;
}
void spfa()
{
	memset(d,0x3f,sizeof(d));
	q.push(s);
	d[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=h[u];i;i=w[i].next)
		{
			int to=w[i].to;
			if(d[u]+w[i].v<d[to])
			{
				d[to]=d[u]+w[i].v;
				if(!vis[to])
				{
					q.push(to);
					vis[to]=1;
				}
			}
		}
	}
}
int main()
{
	scanf("%d%d%d%d%d%d",&l1,&l2,&l3,&c1,&c2,&c3);
	scanf("%d",&n);
	scanf("%d%d",&s,&t);
	for(int i=2;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)//避免重边
	{
		if(i==j) continue;
		if(a[j]-a[i]>l3) break;//简单优化,速度影响不大
		if(a[j]-a[i]<=l1)
		{
			add(i,j,c1);
			add(j,i,c1);
		}
		else if(a[j]-a[i]>l1&&a[j]-a[i]<=l2)
		{
			add(i,j,c2);
			add(j,i,c2);
		}
		else if(a[j]-a[i]>l2&&a[j]-a[i]<=l3)
		{
			add(i,j,c3);
			add(j,i,c3);
		}
	}
	spfa();
	printf("%d",d[t]);
}

猜你喜欢

转载自blog.csdn.net/dy_dream/article/details/80083519