HDU 3339 In Action(最短路+背包)题解

思路:最短路求出到每个点的最小代价,然后01背包,求出某一代价所能拿到的最大价值,然后搜索最后结果。

代码:

#include<cstdio>
#include<set>
#include<cmath>
#include<stack>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 100+5;
const int INF = 0x3f3f3f3f;
int lowcost[maxn],cost[maxn][maxn];
int dp[10005],power[maxn];
bool vis[maxn];
int n,m;
void Dijkstra(int st){
    for(int i = 0;i <= n;i++){
        lowcost[i] = cost[0][i];
        vis[i] = false;
    }
    lowcost[st] = 0;
    for(int i = 0;i < n;i++){
        int k = -1,MIN = INF;
        for(int j = 0;j <= n;j++){
            if(!vis[j] && lowcost[j] < MIN){
                MIN = lowcost[j];
                k = j;
            }
        }
        if(k == -1) break;
        vis[k] = true;
        for(int j = 0;j <= n;j++){
            if(!vis[j] && lowcost[j] > lowcost[k] + cost[k][j]){
                lowcost[j] = lowcost[k] + cost[k][j];
            }
        }
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(cost,INF,sizeof(cost));
        scanf("%d%d",&n,&m);
        while(m--){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            cost[u][v] = cost[v][u] = min(cost[u][v],w);
        }
        for(int i = 1;i <= n;i++)
            scanf("%d",&power[i]);
        int st = 0;
        for(int i = 1;i <= n;i++){
            st += power[i];
        }
        st = st / 2 + 1;

        Dijkstra(0);
        int ALL = 0;
        for(int i = 1;i <= n;i++){
            if(lowcost[i] != INF)
                ALL += lowcost[i];
        }
        memset(dp,0,sizeof(dp));
        for(int i = 1;i <= n;i++){
            if(lowcost[i] == INF) continue;
            for(int j = ALL;j >= lowcost[i];j--){
                dp[j] = max(dp[j],dp[j - lowcost[i]] + power[i]);
            }
        }
        int Min = -1;
        for(int i = 0;i <= ALL;i++){
            if(dp[i] >= st){
                Min = i;
                break;
            }
        }
        if(Min != -1) printf("%d\n",Min);
        else printf("impossible\n");
    }
    return 0;
}

 

posted @ 2018-08-14 11:24  KirinSB  阅读(154)  评论(0编辑  收藏  举报