Yaroslav and Time (简单最短路)

Sample Input
Input
3 1000
1000
0 0
0 1
0 3
Output
2000
Input
3 1000
1000
1 0
1 1
1 2
Output
1000


题意 : 坐标上有n个点,没走一步要花d时间 ;除了起点和终点,其他的点都有个宝箱,每个宝箱可以加时间;
输出从起点到终点,刚开始最少要带多少时间(走一步要花时间,到达一个宝箱有时间加);
可以求出任意两点的距离,距离是步数乘以d ;即从a点到b点的时间花费,但走到b点又有时间加,
所以时间a->b的时间花费为: 步数*d-b宝箱的时间 ;之后跑一遍最短路即可


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std ;
struct node
{
int x,y ;
long long w ;      //宝箱里的时间
}e[200]; 
long long m[200][200] ,d ;


long long dist(int a,int b)     //任意两点时间话费
{
       long long ans=0;
  ans = abs(e[a].x-e[b].x)+abs(e[a].y-e[b].y) ; 
       return ans*d ;          



int main()
{
int n;
while(~scanf("%d%d",&n,&d))
{
e[1].w=e[n].w=0;
memset(m,0,sizeof(m));
for(int i = 2 ; i < n ; i++)
{
   scanf("%lld",&e[i].w);     //除起点和终点外的宝箱时间
}
for(int i = 1 ; i <= n ; i++)
{
  scanf("%d%d",&e[i].x,&e[i].y);
}
for(int i = 1 ; i <= n ; i++)
{
 for(int j =1 ; j<=n;j++)
 {      
        if(i==j) continue ;
      long long num = dist(i,j);
      m[i][j] = num-e[j].w ;    //i->j的实际时间花费
 }
}
for(int k = 1 ; k <= n ; k++)    //弗洛伊德
  for(int i = 1 ; i <= n ; i++)
    for(int j = 1 ; j <= n ; j++)
     {   
          if(m[i][j]> m[i][k]+m[k][j])
             m[i][j] = m[i][k]+m[k][j] ;
     }
printf("%lld\n",m[1][n]);     
}
return 0;
}

你可能感兴趣的:(Yaroslav and Time (简单最短路))