HDU-3339-In Action(最短路+01背包)

题目
题意:每个坦克从0出发到1-n个城市 最终停在哪个城市会得到这个城市的电力。总部有多辆坦克。问得到总电力>= 所有城市的总电力的一半。走过的路最短为多少。
最短路+背包。。 。 。注意背包要装满 。

#include <queue>
#include <cmath>
#include <cstring>
#include <cstdio>
#define  m(a,b) memset(a,b,sizeof a)
#define mak(a,b) make_pair(a,b)
#define sdd(a,b) scanf("%d%d",&a,&b)
#define pi pair<int,int>
using namespace std;
const int N=105+2;
const int M=10000+2;
const int INF=0x3f3f3f3f;
int tot,s,t,n,m;
int head[N],d[N],dp[M*100],w[N];
bool vis[N];
struct Edge{int to,len,nex;}edge[M*2];
priority_queue<pair<int,int> >q;
void add(int from,int to,int len)
{
    edge[++tot]=(Edge){to,len,head[from]};head[from]=tot;
    edge[++tot]=(Edge){from,len,head[to]};head[to]=tot;
}
void dijkstra()
{
    while(!q.empty())
        q.pop();
    d[0]=0;
    q.push(mak(0,0));
    vis[0]=0;
    while(!q.empty())
    {
        int x=q.top().second;
        q.pop();
        if(vis[x])
            continue;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nex)
        {
            int y=edge[i].to,l=edge[i].len;
            if(d[y]>d[x]+l)
            {
                d[y]=d[x]+l;
                q.push(mak(-d[y],y));
            }
        }
    }
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        sdd(n,m);
        m(head,0);
        m(d,INF);
        tot=0;
        for(int i=0;i<=n;i++)
           head[i]=0,d[i]=INF,vis[i]=0;
        int a,b,l;
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&l);
            add(a,b,l);
        }
        dijkstra();
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&w[i]);
            sum+=w[i];
        }
        int x=sum/2+1;
        
//        int D=0;
//        for(int i=1;i<=n;i++)
//            if(d[i]!=INF)
//                D+=d[i];
//        for(int i=1;i<=D;i++)
//            dp[i]=-INF;
//        for(int i=1;i<=n;i++)
//        {
//            if(d[i]==INF)
//                continue;
//            for(int j=D;j>=d[i];j--)
//                dp[j]=max(dp[j],dp[j-d[i]]+w[i]);
//        }
//        bool flag=0;
//        for(int i=0;i<=D;i++)
//            if(dp[i]>=x)
//            {
//                printf("%d\n",i);
//                flag=1;
//                break;
//            }
//        if(!flag)
//            puts("impossible");
//路径长度作为背包容量  sum作为价值

//----------------------------------------------------------------

//sum作为容量,d[i]作为价值  最短路径即为最小价值
        for(int i=1;i<=sum;i++)
            dp[i]=INF;
        dp[0]=0;
        for(int i=1;i<=n;i++)
        {
            if(d[i]==INF)
                continue;
            for(int j=sum;j>=w[i];j--)
            {
                dp[j]=min(dp[j],dp[j-w[i]]+d[i]);
            }
        }
        int ans=INF;
        for(int i=x;i<=sum;i++)
            ans=ans<dp[i]?ans:dp[i];
        if(ans!=INF)
            printf("%d\n",ans);
        else
            puts("impossible");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/87870598
今日推荐