【题意】n个物品,有wi和vi,组成若干个联通块,只能选取一个联通块,问得到m的价值时最小要多少空间(v)。n<=50,v<=10^7

【题解】

先用并查集找出各个联通块。

这题主要就是v太大了,跟以往的背包不同。

我们回想01背包,f[j+v[i]]=max(f[j]+w[i]);

在这里面很明显很多状态都没有用。

优化:如果有2个状态,v1<=v2 && w1>=w2 则(v2,w2)这个状态是没有用的。

我们回到滚动数组中:

f[i][j+v[i]]=max(f[i^1][j]+w[i]);

那么我们可以用两个优先队列,q0存以前的f[i-1],q1存当前的f[i]。

我们在求f[i]的时候,就把q0一个个pop出来,更新后放到q1里面去。

做完i,我们要把q1放到q0,然后做i+1。

在把q1放到q0的时候就把没用的状态去掉(对于(v,val),先按val从大到小排序,再按v从小到大排序,对同样的val取最小的v)。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std; typedef long long LL;
const LL N=,INF=(LL)1e15;
LL n,m,fa[N],t[N],w[N],c[N][N];
struct node{LL v,val;}; struct cmp
{
bool operator () (node &x,node &y)
{
if(x.val==y.val) return x.v<y.v;
return x.val<y.val;
}
}; priority_queue<node,vector<node>,cmp> q0,q1; LL findfa(LL x)
{
if(fa[x]==x) return x;
return findfa(fa[x]);
} LL minn(LL x,LL y){return x<y ? x:y;} int main()
{
freopen("a.in","r",stdin);
freopen("me.out","w",stdout);
int T,cas=;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=n;i++)
{
int num,xx;
scanf("%lld%lld%d",&t[i],&w[i],&num);
for(int j=;j<=num;j++)
{
scanf("%d",&xx);
fa[findfa(i)]=findfa(xx);
}
}
memset(c,,sizeof(c));
for(int i=;i<=n;i++)
{
fa[i]=findfa(i);
c[fa[i]][++c[fa[i]][]]=i;
}
node x,p,f;
LL ans=INF;
for(int k=;k<=n;k++) if(c[k][])
{
// printf("k = %d\n",k);
while(!q0.empty()) q0.pop();
while(!q1.empty()) q1.pop();
x.v=;x.val=;
q0.push(x);
for(int j=;j<=c[k][];j++)
{
int i=c[k][j];
while(!q0.empty())
{
x=q0.top();q0.pop();q1.push(x);
f.v=x.v+t[i];
f.val=x.val+w[i];
if(f.v>=ans) continue;
if(f.val>=m) {ans=minn(ans,f.v);continue;}
q1.push(f);
}
LL mn=INF;
while(!q1.empty())
{
x=q1.top();q1.pop();
if(x.val>=m) ans=minn(ans,x.v);
if(x.v<mn) mn=x.v,q0.push(x);
// printf("v = %lld val = %lld\n",x.v,x.val);
}
}
// f[i^1][v+c[i]]=maxx(f[i^1][v+c[i]],f[i][v]+w[i]]);
}
if(ans<INF) printf("Case %d: %lld\n",++cas,ans);
else printf("Case %d: Poor Magina, you can't save the world all the time!\n",++cas);
}
return ;
}

【hdu3080】01背包(容量10^7)的更多相关文章

  1. HLOJ1366 Candy Box 动态规划(0-1背包改)

    题目描述: 给出N个盒子(N<=100),每个盒子有一定数量的糖果(每个盒子的糖果数<=100),现在有q次查询,每次查询给出两个数k,m,问的是,如果从N个盒子中最多打开k个盒子(意思是 ...

  2. 2018.08.10 atcoder Median Sum(01背包)

    传送门 题意简述:输入一个数组an" role="presentation" style="position: relative;">anan. ...

  3. HDU 3339 In Action【最短路+01背包模板/主要是建模看谁是容量、价值】

     Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the n ...

  4. POJ3211 Washing Clothes[DP 分解 01背包可行性]

    Washing Clothes Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 9707   Accepted: 3114 ...

  5. 【BZOJ-2427】软件安装 Tarjan + 树形01背包

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 960  Solved: 380[Submit][Status ...

  6. hdu2546 01背包

    http://acm.split.hdu.edu.cn/showproblem.php?pid=2546 01背包问题,首先拿出5元买最贵的东西,那接下来就是背包容量m-5,物品数量n-1 的01背包 ...

  7. hdu 2955 01背包

    http://acm.hdu.edu.cn/showproblem.php?pid=2955 如果认为:1-P是背包的容量,n是物品的个数,sum是所有物品的总价值,条件就是装入背包的物品的体积和不能 ...

  8. FOJProblem 2214 Knapsack problem(01背包+变性思维)

    http://acm.fzu.edu.cn/problem.php?pid=2214 Accept: 4    Submit: 6Time Limit: 3000 mSec    Memory Lim ...

  9. hdu 3466 排序01背包

    也是好题,带限制的01背包,先排序,再背包 这题因为涉及到q,所以不能直接就01背包了.因为如果一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m], ...

随机推荐

  1. How to add a webpart to your website

          I have download a webpart that can play media on the website from the internet.Then how to add ...

  2. 【jQuery】 js 对象

    [jQuery] js 对象 一.  创建对象的三种方式 <script> var v1 = new Object(); v1.name = "name1"; v1.a ...

  3. OpenCV入门:(二:加载,显示,修改以及保存图片)

    目标: 1.从图片文件打开图片(imread) 2.显示图片(namedWindow和imshow) 3.转换当前图片为灰色图片(cvtColor) 4.保存图片(imwrite) 代码: #incl ...

  4. NMON记录服务器各项性能数据

    1.将下载下来的nmon文件通过ftp传入服务器下,将nmon权限全开chmod +x nmon 2.查看nmon可以看到如下内容 查看各项指标 输入C,CPU数据 M,内存 N,网络 D,磁盘 T, ...

  5. 接口自动化测试框架Karate入门

    介绍 在这篇文章中,我们将介绍一下开源的Web-API自动化测试框架--Karate Karate是基于另一个BDD测试框架Cucumber来建立的,并且共用了一些相同的思想.其中之一就是使用Gher ...

  6. drf 缓存扩展

    drf缓存给了一个非常方便的扩展,使用起来相当方便 1-   安装 pip install drf-extensions 2-配置 在settings里面增加两项配置 # drf扩展REST_FRAM ...

  7. linux下安装redis及主从配置

    安装比较简单,确保linux安装有gcc # gcc -v 查看gcc版本,如果没有yum安装即可 安装开始 1.redis-3.2.8.tar.gz 上传至服务器 (百度网盘:http://pan. ...

  8. 关于iframe的使用 以及自适应页面高度

    1. <a href="port" target="frame_view">港口资料</a> <iframe id="e ...

  9. 用JAVA写一个多线程程序,写四个线程,其中二个对一个变量加1,另外二个对一个变量减1

    package com.ljn.base; /** * @author lijinnan * @date:2013-9-12 上午9:55:32 */ public class IncDecThrea ...

  10. Java开发JDBC连接数据库

    Java开发JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含6个步骤: JDBC五部曲1.加载驱动2.获得链接3.获取statement对象 4.执行SQL语句5.产生resultset对 ...