【网络流24题】汽车加油行驶 最短路

为什么网络流24题里会有最短路……
原题走这里

题目描述比较繁琐,重点在于如何建图
题目中一个重要的点就是“加满油后可以行驶K格”
可以将其视作为让汽车油量变为K,汽车每走一格就消耗一单位油,没油时就要再加油
K<=10一看就知道是分层图最短路

1~k每一种油量建一层图
每走一格就会少一单位油,也就是连到下一层图
加油就是又重新回到k层
SPFA即可,这里写了个LLL

代码如下:

#include 
using namespace std;
inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node
{
    int x,y,s;
    node(int _x,int _y,int _s)
    {
        x=_x;
        y=_y;
        s=_s;
    }
};
const int m[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int n,k,A,B,C,d[101][101][11];
bool b[101][101][11],a[101][101];
queue q;
int spfa()
{
    q.push(node(1,1,k));
    memset(d,0x3f,sizeof(d));
    d[1][1][k]=0;
    while(!q.empty())
    {
        node f=q.front();
        int X=f.x,Y=f.y,S=f.s;
        b[X][Y][S]=0;
        q.pop();
        if(a[X][Y]&&Sif(d[X][Y][k]>d[X][Y][S]+A)
            {
                d[X][Y][k]=d[X][Y][S]+A;
                if(!b[X][Y][k])
                {
                    b[X][Y][k]=1;
                    q.push(node(X,Y,k));
                }
            }
        }
        else
        {
            if(S)
            {
                for(int i=0;i<4;i++)
                {
                    int xx=X+m[i][0],yy=Y+m[i][1];
                    if(xx>0&&xx<=n&&yy>0&&yy<=n&&d[xx][yy][S-1]>d[X][Y][S]+(i<2?0:B))
                    {
                        d[xx][yy][S-1]=d[X][Y][S]+(i<2?0:B);
                        if(!b[xx][yy][S-1])
                        {
                            b[xx][yy][S-1]=1;
                            q.push(node(xx,yy,S-1));
                        }
                    }
                }
            }
            if(d[X][Y][k]>d[X][Y][S]+A+C)
            {
                d[X][Y][k]=d[X][Y][S]+A+C;
                if(!b[X][Y][k])
                {
                    b[X][Y][k]=1;
                    q.push(node(X,Y,k));
                }
            }
        }
    }
    int ret=0x3f3f3f3f;
    for(int i=0;i<=k;i++)
    {
        ret=min(ret,d[n][n][i]);
    }
    return ret;
}
int main()
{
    freopen("trav.in","r",stdin);
    freopen("trav.out","w",stdout);
    cin>>n>>k>>A>>B>>C;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            a[i][j]=read();
        }
    }
    cout<

你可能感兴趣的:(【网络流24题】汽车加油行驶 最短路)