In Action-HDU - 最短路-01包

  • 题意:
  • Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the number of nuclear weapons have soared across the globe.
  • 自从1945年曼哈顿计划小组在美国引爆了第一颗原子弹,世界核武器的数量已经飙升了。
  •  
  • Nowadays,the crazy boy in FZU named AekdyCoin possesses some nuclear weapons andwanna destroy our world. Fortunately, our mysterious spy-net has gotten his plan. Now, we need to stop it.
  • 如今,FZU的一个名为AekdyCoin的疯狂的男孩拥有一些核武器,并想摧毁我们的世界。幸运的是,我们的神秘间谍网络已经得到了他的计划。现在,我们需要阻止它。
  •  
  • But the arduous task is obviously not easy. First of all, we know that the operating system of the nuclear weapon consists of some connected electric stations, which forms a huge and complex electric network. Every electric station has its power value. To start the nuclear weapon, it must cost half of the electric network's power. So first of all, we need to make more than half of the power diasbled. Our tanks are ready for our action in the base(ID is 0), and we must drive them on the road. As for a electric station, we control them if and only if our tanks stop there. 1 unit distance costs 1 unit oil. And we have enough tanks to use.
  • 但是,这个艰巨的任务显然是不容易的。首先,我们知道,核武器的操作系统包括一些连接的电站,这形成了一个庞大而复杂的电网。每个电站都有其电力值。要启动核武器,就必须花费电网的电力的一半。所以首先,我们需要让超过一半的电力失效。我们的坦克们已经在基地(ID为0)为本次行动准备好,我们必须让他们开上道路。对于一个电站,我们控制他们当且仅当我们的坦克停在那里。 1单位距离花费1个单位的石油。并且我们有足够的坦克使用。
  •  
  • Now our commander wants to know the minimal oil cost in this action.
  • 现在,我们的指挥官想知道这个行动的最小油耗。
  • 思路:
  • 单源最短路从0点出发拍坦克去占领各个点 尽可能的 油耗少并且占领的电力大于总电流的一半。
  • 以总 油耗为背包容量进行背包dp (注意重边dp数组大小的处理)
  • #include<bits/stdc++.h>
    using  namespace std;
    #define maxn 10006
    #define inf 0x3f3f3f3f
    int mmp[maxn][maxn],prize[maxn];
    int dis[maxn],vis[maxn],dp[maxn*10];
    int t,n,m,u,v,w,sum,cont,flag;
    void dijstra()
    {
        for(int i=0; i<=n; i++)
            dis[i]=mmp[0][i];
        dis[0]=0;
        vis[0]=1;
        for(int i=0; i<n; i++)
        {
            int temp=inf,k=-1;
            for(int j=0; j<=n; j++)
                if(!vis[j]&&dis[j]<temp)
                    temp=dis[k=j];
                    if(k==-1)
                        break;
            vis[k]=1;
            for(int j=0; j<=n; j++)
                if(dis[j]>dis[k]+mmp[k][j]&&!vis[j])
                    dis[j]=dis[k]+mmp[k][j];
        }
    }
    int main()
    {
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            for(int i=0; i<=n; i++)
            {
                vis[i]=prize[i]=0;
                dis[i]=inf;
                for(int j=0; j<=n; j++)
                    mmp[i][j]=inf;
            }
            memset(dp,0,sizeof(dp));
            cont=sum=flag=0;
            while(m--)
            {
                cin>>u>>v>>w;
                mmp[u][v]=mmp[v][u]=min(mmp[u][v],w);
            }
            for(int i=1; i<=n; i++)
            {
                cin>>prize[i];
                sum+=prize[i];
            }
            dijstra();
            for(int i=1; i<=n; i++)
                if(dis[i]!=inf)
                    cont+=dis[i];
            for(int i=1; i<=n; i++)
            {
                    for(int j=cont; j>=dis[i]; j--)
                    {
                        dp[j]=max(dp[j],dp[j-dis[i]]+prize[i]);
                    }
            }
            for(int i=0; i<=cont; i++)
                if(dp[i]>sum/2.0)
                {
                    cout<<i<<endl;
                    flag=1;
                    break;
                }
            if(!flag)
                cout<<"impossible"<<endl;
        }
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/82012888