【最短路】汽车加油

来源:互联网 发布:毒萝脸型数据 编辑:程序博客网 时间:2024/05/06 17:54

1、汽车加油(oi.pas/cpp)

 

【问题描述】

一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。

对于给定的n和k个加油站位置,编程计算最少加油次数。

【数据输入】

第一行有2 个正整数n和 k(1<n<4000,1<m<1000),表示汽车加满油后可行驶n公里,且旅途中有k个加油站。接下来的1行中,有 k+1个的整数(每个整数不超过100),表示第 k个加油站与第k-1个加油站之间的距离。第0个加油站表示出发地,汽车已加满油。第k+1个加油站表示目的地。

【数据输出】

输出最少加油次数。如果无法到达目的地,则输出“No Solution”。

 

【输入样例】

7 7

1 2 3 4 5 1 6 6

 

【输出样例】

4


标程方法是贪心,不知道怎么搞的。

一个点到另外一个点有边的条件是加满油后两地之间距离小于等于n。边权为1.

然后求到终点的距离。


#include <cstdio>#include <cstring>#include <string>bool map[1020][1020];long sum[1020];long d[1020];long cost[1020];long que[1000000];bool inque[1020];long n;long L;long getint(){    long rs=0;bool sgn=1;char tmp;    do tmp = getchar();    while (!isdigit(tmp)&&tmp-'-');    if (tmp=='-'){tmp=getchar();sgn=0;}    do rs=(rs<<3)+(rs<<1)+tmp-'0';    while (isdigit(tmp=getchar()));    return sgn?rs:-rs;}void make(){    for (long i=0;i<n;i++)    {        for (long j=i+1;j<n+1;j++)        {            if (sum[j] > sum[i]+L)                break;            map[i][j] = true;        }    }}void spfa(){    memset(cost,0x7f,sizeof cost);    long l = 0;    long r = 0;    r ++;    que[r] = 0;    cost[0] = 0;    inque[0] = true;    while (l < r)    {        l ++;        long u = que[l];        inque[u] = false;        for (long v=u+1;v<n+1;v++)        {            if (!map[u][v])                break;            if (cost[v] > cost[u] + 1)            {                cost[v] = cost[u] + 1;                if (!inque[v])                {                    inque[v] = true;                    r ++;                    que[r] = v;                }            }        }    }}int main(){    freopen("oi.in","r",stdin);    freopen("oi.out","w",stdout);    L = getint();    n = getint() + 1;    for (long i=1;i<n+1;i++)    {        d[i] = getint();        sum[i] = sum[i-1]+d[i];    }    make();    spfa();    if (cost[n] == 0x7f7f7f7f)        printf("No Solution");    else        printf("%ld",cost[n]-1);    return 0;}



原创粉丝点击