http://poj.org/problem?id=3635 /* 题意:给你n个城市m条路,每个城市有个加油站,但是收费单价不同,现给你几个查询并给定汽车的装油量, 问你从S城市到T城市的最小费用。 解法:基于优先队列的BFS.DP[i][j]代表到i这个点还剩J单位油的最小费用. */ #include<iostream> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; #define inf 0x7fffffff struct node { int v, dist; node(int a, int b) { v = a; dist = b; } }; struct Node { int point;//当前的城市 int fuel;//当前的剩余油量 int value;//到当前城市所发的费用 friend bool operator<(Node a, Node b) { return a.value > b.value; } }; vector<node> graph[1002]; int dp[1002][102]; bool used[1002][102]; int n, m, Q, a[1002], V, S, T, ans; priority_queue<Node> my; int bfs(int s) { Node now, next; int x, y, z; while(!my.empty()) my.pop(); now.point = s;//对于源城市 now.fuel = 0; now.value = 0; dp[s][0] = 0; my.push(now); while(!my.empty()) { now = my.top(); my.pop(); x = now.point; y = now.fuel; z = now.value; used[x][y] = true; if(x == T)//如果到达目的城市 return z; if(y+1 <= V && !used[x][y+1] && dp[x][y+1] > dp[x][y] + a[x])//加油(加一单位的油) { dp[x][y+1] = dp[x][y] + a[x]; next.point = x; next.fuel = y+1; next.value = dp[x][y+1]; my.push(next); } for(int i=0; i<graph[x].size(); i++) { int t = graph[x][i].v; int k = y - graph[x][i].dist;//到达下一个城市后所剩的油量 if(k>=0 && !used[t][k] && z<dp[t][k]) { dp[t][k] = z; next.point = t; next.fuel = k; next.value = dp[t][k]; my.push(next); } } } return -1; } int main() { // freopen("in.txt","r",stdin); int i, j; while(scanf("%d %d", &n, &m) != EOF) { for(i=0; i<n; i++) { graph[i].clear(); scanf("%d", &a[i]); } int u, v, w; for(i=0; i<m; i++) { scanf("%d %d %d", &u, &v, &w); graph[u].push_back(node(v,w)); graph[v].push_back(node(u,w)); } int cas; scanf("%d", &cas); while(cas--) { scanf("%d %d %d", &V, &S, &T); memset(used, 0, sizeof(used)); for(i=0; i<n; i++) for(j=0; j<=100; j++) dp[i][j] = inf; ans = bfs(S); if(ans == -1) printf("impossible/n"); else printf("%d/n", ans); } } return 0; }