UVA-11367 Full Tank? (dijkstra)
题目大意:有n个加油站,每个加油站的油价已知,并且已知油箱的大小,问能否从起点走到终点,若能,找出最小油费。
题目分析:记得在做暴力搜索的时候做过这道题,不算难。但是这次是用dijkstra算法做的,时间复杂度不理想,差一点超时(1.9s,限制是2s)。用BFS做的话要快很多。
代码如下:
# include<iostream> # include<cstdio> # include<queue> # include<cstring> # include<algorithm> using namespace std; # define REP(i,s,n) for(int i=s;i<n;++i) # define CL(a,b) memset(a,b,sizeof(a)) const int INF=1<<30; struct Node { int u,k; Node(int _u,int _k):u(_u),k(_k){} }; const int N=1005; struct Edge { int to,nxt,w; }; Edge e[N*20]; int inq[N][105],dis[N][105],head[N],p[N],n,m,cnt; void add(int u,int v,int w) { e[cnt].to=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt++; } int dijkstra(int C,int s,int t) { CL(inq,0); REP(i,0,n) REP(j,0,C+1) dis[i][j]=INF; queue<Node>q; q.push(Node(s,0)); dis[s][0]=0; while(!q.empty()) { Node top=q.front(); q.pop(); int u=top.u,k=top.k; inq[u][k]=0; for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].to; if(k>=e[i].w&&dis[v][k-e[i].w]>dis[u][k]){ dis[v][k-e[i].w]=dis[u][k]; if(!inq[v][k-e[i].w]){ inq[v][k-e[i].w]=1; q.push(Node(v,k-e[i].w)); } } if(k<C&&dis[u][k+1]>dis[u][k]+p[u]){ dis[u][k+1]=dis[u][k]+p[u]; if(!inq[u][k+1]){ inq[u][k+1]=1; q.push(Node(u,k+1)); } } } } int res=INF; REP(i,0,C+1) res=min(res,dis[t][i]); return res; } int main() { int a,b,c,query; while(~scanf("%d%d",&n,&m)){ cnt=0; CL(head,-1); REP(i,0,n) scanf("%d",p+i); while(m--) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } scanf("%d",&query); while(query--) { scanf("%d%d%d",&a,&b,&c); int k=dijkstra(a,b,c); if(k==INF) printf("impossible\n"); else printf("%d\n",k); } } return 0; }