http://poj.org/problem?id=3635
题意:有 n 个城市 ,每个 城市的 油价 不一样 ,已知 各 城市之间的距离 ,(假设 一 单位 距离 耗费一单位的 油量)一辆车 的 油箱 最多可以 装 c 升油,求从 s 到 e,的 最小 花费油量,如果不能到达 输出 impossible 。
题解:一开始 自己 写了 个,到达每一点后枚举 可以 增加的 油量 结果 tle (太多 无用的状态了)。。。。。。
dp[i][j] 表示 到达 城市 i 剩余油量 为 j 的 最小花费;
首先到达每个城市的后 要加的 油量 是 不确定 的 ,所以 我们要 将 每一个城市 拆成 c+ 1 个点,(不是直接的拆分),在 每一个 状态节点 我们有 两种选择 ,1 : 油量 加 1 (这个 就 相当于 拆分 成了 c+1 个节点);2:不加油 直接 走向 可 扩展的节点 。
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<
set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<
string>
11
#define Min(a,b) a<b?a:b
12
#define Max(a,b) a>b?a:b
13
#define CL(a,num) memset(a,num,sizeof(a));
14
#define eps 1e-12
15
#define inf 0x7fffffff
16
17
//
freopen("data.txt","r",stdin);
18
const
double pi = acos(-
1.0);
19 typedef __int64 ll;
20
const
int maxn =
1200 ;
21
using
namespace std;
22
struct node
23 {
24
25
int v;
26
int len ;
27
int next ;
28 }p[maxn*
10*
2] ;
29
struct qnode
30 {
31
int d;
32
int u ;
33
int cost ;
34 qnode(
int x,
int y,
int z):u(x),d(y),cost(z){}
35 friend
bool
operator < (qnode a,qnode b)
36 {
37
return a.cost > b.cost ;
38 }
39 };
40
int num,a[maxn],next[maxn],dp[maxn][
102],n,m,vis[maxn][
102];
41
void add(
int u ,
int v,
int len)
42 {
43 p[num].v = v;
44 p[num].len = len ;
45 p[num].next = next[u] ;
46 next[u] = num++;
47 }
48 priority_queue<qnode>que;
49
int bfs(
int s,
int e,
int c)
50 {
51
52
int i , j ;
53
while(!que.empty())que.pop();
54
55
for(i =
0 ; i <= n;i++ )
56 {
57
for(j =
0; j<= c;j++)
58 dp[i][j] = inf ;
59 }
60
61 CL(vis,
0);
62
63 dp[s][
0] =
0 ;
64
65 que.push(qnode(s,
0,
0));
66
67
while(!que.empty())
68 {
69 qnode b = que.top();que.pop();
70
71
int u = b.u;
72
int cost = b.cost;
73
int d = b.d ;
74 vis[u][d] =
1;
//
标记 已经找到了 的 最小的 ,下面就不用 再扩展的 此节点了
75
if(u == e)
return cost ;
//
用的是 优先队列 所以 出来的定是 最小的 ;
76
77
if(d+
1 <= c &&!vis[u][d +
1] && dp[u][d+
1]> dp[u][d] + a[u])
//
油量 加 1
78
{
79 dp[u][d +
1] = dp[u][d] + a[u] ;
80 que.push(qnode(u,d+
1,dp[u][d+
1]));
81
82 }
83
for(i = next[u];i!= -
1;i = p[i].next)
//
直接 走向 相邻 节点 ;
84
{
85
int v = p[i].v ;
86
int len = p[i].len ;
87
88
if(d >= len &&!vis[v][d - len] && dp[v][d - len] > cost)
89 {
90 dp[v][d - len] = cost ;
91 que.push(qnode(v,d - len,cost));
92 }
93
94
95 }
96
97
98 }
99
100
101
return -
1 ;
102 }
103
int main()
104 {
105
//
freopen("data.txt","r",stdin);
106
int s,e,c,i,x,y,d,q;
107
while(~scanf(
"
%d%d
",&n,&m))
108 {
109
for(i =
0;i < n;i++) scanf(
"
%d
",&a[i]) ;
110
111 CL(next,-
1) ;
112 num =
0 ;
113
for(i =
0 ;i< m;i++)
114 {
115 scanf(
"
%d%d%d
",&x,&y,&d);
116 add(x,y,d);
117 add(y,x,d);
118 }
119
120 scanf(
"
%d
",&q);
121
122
while(q--)
123 {
124 scanf(
"
%d%d%d
",&c,&s,&e);
125
int ans = bfs(s,e,c);
126
if(ans != -
1)printf(
"
%d\n
",ans);
127
else puts(
"
impossible
");
128 }
129 }
130
131 }