题意:给出一个有权无向图,顶点代表不同的城市,给出每个城市的汽油价格,一个单位的路程要消耗一个单位的汽油。然后给出汽车油箱的容量c,起点和终点,求出起点到终点的最小花费。
思路:把每个点拆成c+1个点,每次只能加1个单位的汽油,然后用dijstra求解。
View Code
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define N 1010 #define M 100010 #define inf 0x3fffffff int pre[N],p[N],fee[N*110]; struct edge{ int to,next,w; }e[M*2]; int cnt,n,m,C; void add(int a,int b,int w) { e[cnt].next=pre[a]; e[cnt].to=b; e[cnt].w=w; pre[a]=cnt++; } struct node{ int w,id; bool operator <(const node &x)const { return w>x.w; } }; int get_id(int x,int y) { return x*C+y; } void div_id(int id,int &x,int &y) { x=id/C; y=id%C; } int dijstra(int s,int t) { priority_queue<node> q; node in; for(int i=0;i<n*C;i++) fee[i]=inf; in.id=get_id(s,0); in.w=0; q.push(in); fee[in.id]=0; while(!q.empty()) { int id=q.top().id; int u,x; div_id(id,u,x); //cout<<id<<":: "<<u<<":"<<x<<endl; if(u==t)return q.top().w; q.pop(); int id0=0; if(x<C-1) { id0=get_id(u,x+1); if(fee[id]+p[u]<fee[id0]) { fee[id0]=fee[id]+p[u]; in.id=id0; in.w=fee[id0]; q.push(in); } } for(int edg=pre[u];edg!=0;edg=e[edg].next) { int v=e[edg].to; if(x>=e[edg].w) { id0=get_id(v,x-e[edg].w); if(fee[id]<fee[id0]) { fee[id0]=fee[id]; in.id=id0; in.w=fee[id0]; q.push(in); } } } } return -1; } int main() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&p[i]); } memset(pre,0,sizeof(pre)); cnt=1; for(int i=1;i<=m;i++) { int a,b,w; scanf("%d%d%d",&a,&b,&w); add(a,b,w); add(b,a,w); } int ca; scanf("%d",&ca); while(ca--) { int s,en,c; scanf("%d%d%d",&c,&s,&en); C=c+1; int x=dijstra(s,en); if(x==-1)printf("impossible\n"); else printf("%d\n",x); } return 0; }