(网络流24题大多需要spj,所以需要一个有spj的oj,本系列代码均在www.oj.swust.edu.cn测试通过)
不知道为什么回混进来这么多奇怪的问题,老子的网络流呢?
这道题只要把搞一个状态f[i][j][k]表示坐标为(i,j)的点剩余油量为k,按照题目描述跑一边最短路即可。
唉,不含加油费活生生让我看成了不用加油费,读题杀要死人啊。
Dijkstra让我活生生改了个名,不要在意哦
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<string>
#include<cstring>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
int n,va,vb,vc;
int dis[101][101][11];
struct point
{
int x,y,k;
point (int _,int __,int ___):x(_),y(__),k(___){}
bool operator <(point b) const
{
return dis[x][y][k]>dis[b.x][b.y][b.k];
}
};
priority_queue<point> my_queue;
int k;
bool pd[101][101][11];
int mapp[101][101];
int xx[4]={-1,0,1,0};
int yy[4]={0,-1,0,1};
void djstra()
{
memset(dis,0x1f,sizeof(dis));
dis[1][1][k]=0;
my_queue.push(point(1,1,k));
while(!my_queue.empty())
{
point mid=my_queue.top();
my_queue.pop();
while(pd[mid.x][mid.y][mid.k] && !my_queue.empty()) mid=my_queue.top(),my_queue.pop();
if(pd[mid.x][mid.y][mid.k]) break;
pd[mid.x][mid.y][mid.k]=true;
if(mid.x==n && mid.y==n)
{
cout<<dis[mid.x][mid.y][mid.k];
exit(0);
}
if(mid.k==0) continue;
for(int i=0;i<4;i++)
{
int nx=mid.x+xx[i];
int ny=mid.y+yy[i];
if(nx<1 || nx>n || ny<1 || ny>n) continue;
int ercost=0;
if(i<2) ercost=vb;
if(mapp[nx][ny]==1)
{
if(dis[mid.x][mid.y][mid.k]+ercost+va<dis[nx][ny][k])
{
dis[nx][ny][k]=dis[mid.x][mid.y][mid.k]+ercost+va;
my_queue.push(point(nx,ny,k));
}
}
else
{
if(dis[mid.x][mid.y][mid.k]+ercost+vc+va<dis[nx][ny][k])
{
dis[nx][ny][k]=dis[mid.x][mid.y][mid.k]+ercost+vc+va;
my_queue.push(point(nx,ny,k));
}
}
if(mapp[nx][ny]) continue;
if(dis[mid.x][mid.y][mid.k]+ercost<dis[nx][ny][mid.k-1])
{
dis[nx][ny][mid.k-1]=dis[mid.x][mid.y][mid.k]+ercost;
my_queue.push(point(nx,ny,mid.k-1));
}
}
}
}
int main()
{
scanf("%d%d%d%d%d",&n,&k,&va,&vb,&vc);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&mapp[i][j]);
djstra();
return 0;
}