hdu 1690 Bus System

题意:求到达任意俩点之间的最小消费,也可以说求任意俩点的最短路径啦

分析:很直接的就是用floyd算法,很好写的一个算法,最坑爹的是距离要用__int64保存

当然,对每一次询问都用单源最短路算法的SPFA 也行,不过慢了一点

floyd
#include<iostream>
#include<algorithm>
#include<math.h>
#define MAXN 100+10
using namespace std;
int L[4],C[4],n;
int X[MAXN];
__int64 g[MAXN][MAXN];
int get_dis(int i,int j)
{
int dis=abs(X[j]-X[i]);
if(dis>0 && dis<=L[0])
return C[0];
if(dis>L[0] && dis<=L[1])
return C[1];
if(dis>L[1] && dis<=L[2])
return C[2];
if(dis>L[2] && dis<=L[3])
return C[3];
return -1;
}
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(g[i][k]==-1 || g[k][j]==-1)
continue;
if(g[i][j]==-1 || g[i][k]+g[k][j]<g[i][j])
g[i][j]=g[i][k]+g[k][j];
}
}
int main()
{
int T,m,cas=0;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<4;i++)
scanf("%d",&L[i]);
for(int i=0;i<4;i++)
scanf("%d",&C[i]);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&X[i]);
for(int i=1;i<n;i++)
{
g[i][i]=-1;
for(int j=i+1;j<=n;j++)
g[i][j]=g[j][i]=get_dis(i,j);
}
g[n][n]=-1;
floyd();
int a,b;
printf("Case %d:\n",++cas);
while(m--)
{
scanf("%d %d",&a,&b);
if(g[a][b]!=-1)
printf("The minimum cost between station %d and station %d is %I64d.\n",a,b,g[a][b]);
else printf("Station %d and station %d are not attainable.\n",a,b);
}
}
return 0;
}
spfa
#include<iostream>
#include<algorithm>
#include<math.h>
#define MAXN 100+10
using namespace std;
int g[MAXN][MAXN],n;
int L[4],C[4];
__int64 dist[MAXN];
int X[MAXN],Q[MAXN*MAXN*MAXN];
bool vis[MAXN];
int get_dis(int i,int j)
{
int dis=abs(X[j]-X[i]);
if(dis>0 && dis<=L[0])
return C[0];
if(dis>L[0] && dis<=L[1])
return C[1];
if(dis>L[1] && dis<=L[2])
return C[2];
if(dis>L[2] && dis<=L[3])
return C[3];
return -1;
}
void SPFA(int s)
{ // pri是队列头结点,end是队列尾结点
int i, pri, end, p;
memset(vis, 0, sizeof(vis));
for(int i=0; i<MAXN*MAXN; ++i)
Q[i] = 0;
for (i=1; i<=n; i++)
dist[i] = -1;
dist[s] = 0;
vis[s] = 1;
Q[1] = s; pri = 1; end = 2;
while (pri < end)
{
p = Q[pri];
for (i=1; i<=n; ++i)
{ //更新dis
if(g[p][i]==-1 || dist[p]==-1) continue;
if (dist[i]==-1 || dist[p]+ g[p][i]<dist[i])
{
dist[i] = dist[p]+g[p][i];
if (!vis[i]) //未在队列中
{
Q[end++] = i;
vis[i] = 1;
}
}
}
vis[p] = 0; // 置出队的点为未标记
pri++;
}
}
int main()
{
int T,m,cas=0;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<4;i++)
scanf("%d",&L[i]);
for(int i=0;i<4;i++)
scanf("%d",&C[i]);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&X[i]);
for(int i=1;i<n;i++)
{
g[i][i]=-1;
for(int j=i+1;j<=n;j++)
g[i][j]=g[j][i]=get_dis(i,j);
}
g[n][n]=-1;
int a,b;
printf("Case %d:\n",++cas);
while(m--)
{
scanf("%d %d",&a,&b);
SPFA(a);
if(dist[b]!=-1)
printf("The minimum cost between station %d and station %d is %I64d.\n",a,b,dist[b]);
else printf("Station %d and station %d are not attainable.\n",a,b);
}
}
return 0;
}



原文地址:https://www.cnblogs.com/nanke/p/2365613.html