Hdu 3339 In Action

 

  
    
1 //1. tank必须停在点上才能占领
2  //2. 可以转化成0-1背包,包的“容量”是每个点的能量值,物品的value是耗油量,f[i][j]状态表示达到能量值j,需要的最小耗油量
3  // 需要小的变形 f[i][j] = min(f[i][j], f[i][j+1], f[i-val[i]][j] + d[i]);
4  //3. 先用dijstra求出0点到1~n个点的最短路 d[i];
5 //4. 边的权值可能为0
6 //*5. 可能有多重边,输入时要处理
7 #include <stdio.h>
8 #include <string.h>
9 #define Min(x,y) ((x)<(y)?(x):(y))
10 #define INF 0xfffffff
11 #define NL 110
12
13 int n, m;
14 int e[NL][NL];
15 int d[NL];
16 int val[NL];
17 int f[NL*NL];
18 bool flg[NL];
19
20 void Dij()
21 {
22 int i, j;
23 for (i=1; i<=n; i++)
24 d[i] = INF;
25 d[0] = 0;
26 memset(flg, 0, sizeof(flg));
27 int t = n;
28 while (t--) {
29 int min = INF, u;
30 for (i=0; i<=n; i++) {
31 if (!flg[i] && d[i] < min) {
32 min = d[i];
33 u = i;
34 }
35 }
36 flg[u] = 1;
37 for (int v=0; v<=n; v++) {
38 if (e[u][v] >= 0) {
39 if (d[v] > d[u] + e[u][v])
40 d[v] = d[u] + e[u][v];
41 }
42 }
43 }
44 }
45
46 int main()
47 {
48 int t;
49 int i, j;
50 scanf("%d", &t);
51 while (t--) {
52 scanf("%d%d", &n, &m);
53 int a, b, c;
54 memset(e, -1, sizeof(e));
55 for (i=0; i<m; i++) {
56 scanf("%d%d%d", &a, &b, &c);
57 if (e[a][b] == -1) {
58 e[a][b] = e[b][a] = c;
59 }else {
60 e[a][b] = e[b][a] = Min(e[a][b], c);
61 }
62 }
63 int sum = 0;
64 for (i=1; i<=n; i++) {
65 scanf("%d", &val[i]);
66 sum += val[i];
67 }
68 Dij();
69 for (i=0; i<=sum+1; i++)
70 f[i] = INF;
71 f[0] = 0;
72 for (i=1; i<=n; i++) {
73 for (j=sum; j>=0; j--) {
74 if (j>=val[i]) f[j] = Min(f[j], Min(f[j+1], f[j-val[i]] + d[i]));
75 else f[j] = Min(f[j], f[j+1]);
76 }
77 }
78 for (j=sum; j>=0; j--) {
79 f[j] = Min(f[j], f[j+1]);
80 }
81 int min = f[sum/2+1];
82 if (min == INF) printf("impossible\n");
83 else printf("%d\n", min);
84 }
85 return 0;
86 }

 

你可能感兴趣的:(action)