普通的最短路,只是建图稍微麻烦点。
最坑的地方是一定要用__int64存入数据。。。
下面的代码可以用G++过,把%I64d改成%lld可以用C++过。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fLL;
//4557430888798830399LL;
long long n,s,m;
long long v[1024],path[1024];
long long map[1024][1024],dis[1024];
long long f(long long a,long long b)
{
return a-b>0?a-b:b-a;
}
bool Dijkstra(long long s)
{
long long i,j;
for(i=1;i<=n;i++)
{
v[i]=0;
// path[i]=s;
dis[i]=map[s][i];
}
dis[s]=0;
for(i=1;i<=n;i++)
{
long long min=inf;
long long pos=0;
for(j=1;j<=n;j++)
{
if(!v[j] )
if(dis[j]<min)
{
pos=j;
min=dis[j];
}
}
v[pos]=1;
if(min==inf) return 0;
for(j=1;j<=n;j++)
{
long long p;
if(!v[j])
if(p=map[pos][j]+dis[pos],p<dis[j])
{
dis[j]=p;
// path[j]=pos;
}
}
}
return 1;
}
int main()
{
long long t,s,i,j,a,b,q;
long long l[5],c[5],sta[105];
long long tot=1;
scanf("%I64d",&t);
while(t--)
{
for(i=1;i<=4;i++)
scanf("%I64d",&l[i]);
for(i=1;i<=4;i++)
scanf("%I64d",&c[i]);
scanf("%I64d %I64d",&s,&q);n=s;m=q;
memset(map,0x3f,sizeof(map));
for(i=1;i<=s;i++) //建图的过程
{
scanf("%I64d",&sta[i]);
for(j=1;j<=i;j++) //判断当前点和其他点的距离,并写入权值
{
long long d=f(sta[i],sta[j]);
if(d>0&&d<=l[1]) map[i][j]=map[j][i]=c[1];
else if(d>l[1]&&d<=l[2]) map[i][j]=map[j][i]=c[2];
else if(d>l[2]&&d<=l[3]) map[i][j]=map[j][i]=c[3];
else if(d>l[3]&&d<=l[4]) map[i][j]=map[j][i]=c[4];
}
}
printf("Case %I64d:\n",tot++);
for(i=1;i<=q;i++)
{
scanf("%I64d %I64d",&a,&b);
Dijkstra(a);
if(dis[b]!=inf) printf("The minimum cost between station %I64d and station %I64d is %I64d.\n",a,b,dis[b]);
else printf("Station %I64d and station %I64d are not attainable.\n",a,b);
}
}
return 0;
}