hdu 3339 0-1背包+最短路

hdu 3339 0-1背包+最短路

     本题开始题意理解有问题,以为是坦克一起开到每个地方炸掉station,使总路程最短,于是要考虑各个station之间的路程,而近于搜索暴力,百思不得其解。后来发现题意理解错了。“We have enough tanks”这句话不是白写的,要仔细读题。是把各个坦克开到各个地方守着,就是control(控制)power总量在占据一半以上的station,使之不能启动,于是就可以背包了。
     首先求出各个station到开始位置的单源最短路,这里边数范围是点数范围的平方关系,用Dijkstra和spfa都可以,这是背包里面的价值。各个station总的power是背包容量,每个station的power是物品的容量。在容量一半以上的范围内找价值最小的。

     代码如下:

代码
 1 #include<iostream>
 2 #include<vector>
 3 #include<queue>
 4 using namespace std;
 5 #define MAXM 102
 6 //#define clr(a) memset(a,0,sizeof(a))
 7 #define INF 9999999
 8 struct node
 9 {
10    node (int v0, int dis0):v(v0),dis(dis0){}
11    int v;
12    int dis;
13 };
14 vector<node> map[MAXM];
15 bool visit[MAXM];
16 int n;
17 void spfa(int x,int dis[])
18 {
19    int i;
20    //clr(visit);   
21    for(i = 0; i < (n+1); i++)
22    {
23           dis[i] = INF;
24           visit[i] = false;
25    }
26    visit[x] = true;
27    dis[x] = 0
28    queue<int> q;
29    q.push(x);
30    while(!q.empty())
31    {
32        int u = q.front();
33        q.pop();
34        visit[u] = false;
35        for(i = 0; i < map[u].size(); i++)
36        {
37          node p = map[u][i];
38          if(dis[p.v] > (dis[u] + p.dis))
39          {
40              dis[p.v] = dis[u] + p.dis;
41              if(!visit[p.v])
42              {
43                 visit[p.v] = true;
44                 q.push(p.v);
45              }
46          }
47        }
48    }
49 }
50 int main()
51 {
52    int T,m,i,j,a,b,len,sum,min;
53    int pow[MAXM],oil[MAXM],pack[MAXM*MAXM];
54    scanf("%d",&T);
55    while(T--)
56    {
57        scanf("%d %d",&n,&m);
58        for(i = 0; i <= n; i++)
59            map[i].clear();
60        for(i = 0; i < m;i++)
61        {
62           scanf("%d %d %d",&a,&b,&len);
63           map[a].push_back(node(b,len));
64           map[b].push_back(node(a,len));
65        }
66        sum = 0;
67        for(i = 1;i <= n; i++)
68        {
69            scanf("%d",&pow[i]);
70            sum += pow[i];
71        }
72        for(i = 1; i <= sum; i++)
73            pack[i] = INF;
74        spfa(0,oil);
75        pack[0= 0;
76        for(i = 1; i <= n; i++)
77        {
78          for(j = sum;(j-pow[i]) >= 0;j--)
79          {
80            if((pack[j - pow[i]] + oil[i]) < pack[j])
81                pack[j] = pack[j - pow[i]] + oil[i];
82          }
83        }
84        min = INF;
85        for(i = sum/2+1; i <= sum; i++)
86        {
87           if(min > pack[i])
88               min = pack[i];
89        }
90        if(min != INF)
91            printf("%d\n",min);
92        else
93            printf("impossible\n");
94    }
95 

你可能感兴趣的:(hdu 3339 0-1背包+最短路)