西安邀请赛-D(带权并查集+背包)
题目链接:https://nanti.jisuanke.com/t/39271
题意:给定n个物品,m组限制,每个物品有个伤害值,现在让两个人取完所有物品,要使得两个人取得物品伤害值之和最接近,输出伤害值不小于另一个的人的伤害值,每组限制包括两次数x y,表示物品x和物品y不能由同一个人取得。
思路:思路是通过bfs或并查集将有关系的物品合并为一个物品,合并的物品有两个值,每个人必须分别取每个物品的一个值,然后就是背包问题了。
具体实现就是用root[i]表示i的祖先,a[i]表示i与其祖先的关系(为0表示和祖先放在一边,为1表示和祖先不能放一边),可以得到(x->z=(x->y)^(y->z),x->z表示物品x,z的关系,还有x->y=y->x),然后就可以通过并查集来维护所有限制关系。之后遍历所有祖先等于自己的个数,即合并后的连通块个数,设为k。然后把第i个集合中和与祖先关系为0的都加在b[i][0]上,把第i个集合中和祖先关系为1的都加在b[i][1]上。然后还有个操作就是因为每个人分别取b[i][0],b[i][1]中的一个,要使差值最小,那么可以将b[i][0],b[i][1]同时减一个数使得min(b[i][0],b[i][1])=0,这并不影响答案。这样就是减去min(b[i][0],b[i][1])=0,剩下那个非0的数存进d[i]中,并且将所有d[i]加起来得到sum1。
那么问题就转换为有k个物体,价值为d[i],这里价值和体积一样,在空间为sum/2的背包中,每次有选或不选两种可能,求背包最大的价值为多少。然后就可以得到结果了。说的有点绕,但思路不复杂,理解一下自己写写,代码写得有点乱,不建议看。。
AC代码:
#include<cstdio>
#include<map>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std; int T,n,m,sum1,sum2,sum3,sum4,c[],root[],a[];
int b[][],d[],dp[]; int getr(int k){
if(root[k]==k) return k;
else{
int tmp=root[k];
root[k]=getr(root[k]);
a[k]^=a[tmp];
return root[k];
}
} int main(){
scanf("%d",&T);
while(T--){
memset(b,,sizeof(b));
memset(d,,sizeof(d));
memset(dp,,sizeof(dp));
sum1=,sum2=,sum3=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
root[i]=i,a[i]=;
for(int i=;i<=n;++i)
scanf("%d",&c[i]),c[i]/=,sum1+=c[i];
while(m--){
int x,y,rx,ry;
scanf("%d%d",&x,&y);
rx=getr(x),ry=getr(y);
if(rx==ry) continue;
root[ry]=rx;
a[ry]=^a[y]^a[x];
}
map<int,int> mp;
int k=;
for(int i=;i<=n;++i)
if(getr(i)==i)
mp[i]=++k;
for(int i=;i<=n;++i){
int r=getr(i);
b[mp[r]][a[i]]+=c[i];
}
for(int i=;i<=k;++i)
d[i]=abs(b[i][]-b[i][]),sum2+=d[i],sum3+=min(b[i][],b[i][]);
sum4=sum2/;
for(int i=;i<=k;++i)
for(int j=sum4;j>=d[i];--j)
dp[j]=max(dp[j],dp[j-d[i]]+d[i]);
printf("%d\n",(sum1-(sum3+dp[sum4]))*);
}
return ;
}
西安邀请赛-D(带权并查集+背包)的更多相关文章
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- POJ 1703 Find them, Catch them(带权并查集)
传送门 Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42463 Accep ...
- [NOIP摸你赛]Hzwer的陨石(带权并查集)
题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...
- poj1984 带权并查集(向量处理)
Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 5939 Accepted: 2 ...
- 【BZOJ-4690】Never Wait For Weights 带权并查集
4690: Never Wait for Weights Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 88 Solved: 41[Submit][ ...
- hdu3038(带权并查集)
题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示 ...
- 洛谷OJ P1196 银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
- poj1984 带权并查集
题意:有多个点,在平面上位于坐标点上,给出一些关系,表示某个点在某个点的正东/西/南/北方向多少距离,然后给出一系列询问,表示在第几个关系给出后询问某两点的曼哈顿距离,或者未知则输出-1. 只要在元素 ...
随机推荐
- 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵
题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...
- TensorFlow使用记录 (十四): Multi-task to MNIST + Fashion MNIST
前言 后面工作中有个较重要的 task 是将 YOLOV3 目标检测和 LanNet 车道线检测和到一个网络中训练,特别的是,这两部分数据来自于不同的数据源.这和我之前在 caffe 环境下训练检测整 ...
- typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结
https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...
- 20165213 Exp7 网络欺诈防范
Exp7 网络欺诈防范 一. 实践内容 简单应用SET工具建立冒名网站 1.首先使用sudo vi /etc/apache2/ports.conf 进行查看listen的端口号,若不是80改为80. ...
- LeetCode 82. 删除排序链表中的重复元素 II(Remove Duplicates from Sorted List II)
题目描述 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 1: 输入: 1->2->3->3->4->4->5 输出: ...
- tp5 多条件查询
$where['rc_category_id'] = array('eq',$cid); $where['rc_territory_ids'] = ['like', '%'.$tid.'%']; $l ...
- php怎样获取当前页面文件名
因开发需要,常需要获取当前php文件的文件名.php获取当前文件名方法很简单,程序代码如下: <?php function php_self(){ $php_self=substr($_SERV ...
- Ceph RBD 的实现原理与常规操作
目录 文章目录 目录 前文列表 RBD RBD Pool 的创建与删除 块设备的创建与删除 块设备的挂载与卸载 新建客户端 块设备的扩缩容 RBD 块设备的 Format 1 VS Format 2 ...
- Selenium 2自动化测试实战25(自动化测试模型)
一.自动化测试模型 自动化测试模型介绍:线性测试.模块化驱动测试.数据驱动测试和关键字驱动测试 线性测试:每个测试脚本相对独立,且不产生其他依赖与调用,只是单纯的来模拟用户完整的操作场景.模块化驱动测 ...
- class文件访问标志
class文件中用两个字节共16位代表访问标志(access flags),用于表明该类或接口被访问时能提供的一些信息: 标志名称 标志值 含义 ACC_PUBLIC 0x00 01 是否为Publi ...