Full Tank? UVA - 11367
图论·最短路
题目大意:
n个点m条无向边的图,每个单位的汽油能走1单位距离,每个城市的油价p[i],油箱有上限c, 对于每个询问,求s到t的最小花费。
题解:
d[u][oilu]在d这个点剩余油量为oilu的最小花费。
只要油还够,就可以向与它相连的v转移,d[v][oilu-w(u,v)]
注意如果直接枚举加多少油会T。
因此每次只加一格油,也就是只+p[u]转移到d[u][oilu+1].
感觉一直在刷水题。。。
Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define MP make_pair
using namespace std;
typedef pair<int,int> pii;
const int N = 2005;
const int M = 50005;
const int INF = 0x3f3f3f3f;
int n,m,p[N],q;
struct Edge{
int to,next,w;
}e[M];
int head[N],ec;
void clear(){ memset(head,0,sizeof(head)); ec=0; }
void add(int a,int b,int w){
ec++; e[ec].to=b; e[ec].w=w;
e[ec].next=head[a]; head[a]=ec;
}
bool vis[N][105]; int d[N][105];
void spfa(int s,int t,int c){
memset(vis,false,sizeof(vis));
memset(d,0x3f,sizeof(d));
queue<pii> q; q.push(MP(s,0)); vis[s][0]=true; d[s][0]=0;
while(!q.empty()){
int u=q.front().first; int oilu=q.front().second; q.pop(); vis[u][oilu]=false;
if(oilu+1<=c && d[u][oilu+1]>d[u][oilu]+p[u]){
d[u][oilu+1]=d[u][oilu]+p[u];
if(!vis[u][oilu+1]){
vis[u][oilu+1]=true; q.push(MP(u,oilu+1));
}
}
for(int i=head[u];i;i=e[i].next){
int v=e[i].to; int cost=e[i].w;
if(oilu<cost) continue;
if(d[v][oilu-cost]>d[u][oilu]){
d[v][oilu-cost]=d[u][oilu];
if(!vis[v][oilu-cost]){
vis[v][oilu-cost]=true; q.push(MP(v,oilu-cost));
}
}
}
}
}
int main(){
freopen("a.in","r",stdin);
while(~scanf("%d%d",&n,&m)){
clear();
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
int a,b,w;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&w);
a++; b++;
add(a,b,w); add(b,a,w);
}
scanf("%d",&q);
int s,t,c;
while(q--){
scanf("%d%d%d",&c,&s,&t);
s++; t++;
spfa(s,t,c);
if(d[t][0]==INF) puts("impossible");
else printf("%d\n",d[t][0]);
}
}
}

本文介绍了解决 UVA-11367 题目的方法,该题涉及图论中的最短路径问题。具体地,针对带有燃料限制的路径寻找最小花费,使用 SPFA 算法进行求解。

被折叠的 条评论
为什么被折叠?



