hdu3339 In Action 最短路+01背包

来源:互联网 发布:js设置div不可见 编辑:程序博客网 时间:2024/05/16 11:53
//有n个电站,每一个电站能提供不同的power,//所有tank从0点出发,停在该电站就代表摧毁了该电站,tank从电站到电站之间需要耗费能量//现在有无穷的tank,问最少需要耗费多少油能够摧毁一半以上的power//先用dijkstra求得到每个点的dis[i]//然后用一个01背包得到答案#include<cstdio>#include<cstring>#include<iostream>using namespace std ;const int maxm = 600010 ;const int maxn = 110 ;const int inf = 0x3f3f3f3f;int dp[maxm] ;struct Edge{    int v , w ;    int next ;}edge[maxm] ;int head[maxn] ;int v[maxn] ;int nedge ;int dis[maxn] ;int vis[maxn] ;int n , m ;void addedge(int u , int v , int w){    edge[nedge].v = v ;    edge[nedge].w = w ;    edge[nedge].next = head[u] ;    head[u] = nedge++;}int dijkstra(){    memset(vis , 0 ,sizeof(vis)) ;    for(int i = 1;i <= n;i++)    dis[i] = inf ;    dis[0] = 0 ;    int u = 0;    int sum = 0 ;    while(1)    {        int mi = inf ;int pos ;        for(int i = 0;i <= n;i++)        if(!vis[i] && dis[i] < mi)        mi = dis[pos = i] ;        if(mi == inf)break;        sum += mi ;        vis[pos] = 1;        for(int i = head[pos] ; i != -1 ;i = edge[i].next)        {            int v  = edge[i].v ;            dis[v] = min(dis[v] , dis[pos] + edge[i].w) ;        }    }    return sum ;}int main(){   // freopen("in.txt" ,"r" , stdin) ;    int T ;    scanf("%d" ,&T) ;    while(T--)    {        scanf("%d%d" ,&n , &m) ;        memset(head , -1 , sizeof(head)) ;        nedge = 0 ;        int sum = 0 ;        while(m--)        {            int u ,v , w ;            scanf("%d%d%d" ,&u , &v , &w) ;            addedge(u , v , w) ;            addedge(v , u , w) ;        }        for(int i = 1;i <= n;i++)        scanf("%d" ,&v[i]) ,sum+=v[i] ;        int tmp = dijkstra() ;        memset(dp , 0 , sizeof(dp)) ;        for(int i = 1;i <= n;i++)        {            if(dis[i] == inf)continue ;            for(int j = tmp ;j >= dis[i];j--)            dp[j] = max(dp[j] , dp[j-dis[i]] + v[i]) ;        }        int ans = inf;        for(int i = 0;i <= tmp ;i++)        if(dp[i] >= (sum)/2 + 1)        {            ans = i ;            break;        }        if(ans == inf)puts("impossible");        else        cout<<ans<<endl;    }}
0 0
原创粉丝点击