[HDU 3712] Fiolki (带边权并查集+启发式合并)
[HDU 3712] Fiolki (带边权并查集+启发式合并)
题面
化学家吉丽想要配置一种神奇的药水来拯救世界。
吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号)。初始时,第i个瓶内装着g[i]克的第i种物质。吉丽需要执行一定的步骤来配置药水,第i个步骤是将第a[i]个瓶子内的所有液体倒入第b[i]个瓶子,此后第a[i]个瓶子不会再被用到。瓶子的容量可以视作是无限的。
吉丽知道某几对液体物质在一起时会发生反应产生沉淀,具体反应是1克c[i]物质和1克d[i]物质生成2克沉淀,一直进行直到某一反应物耗尽。生成的沉淀不会和任何物质反应。当有多于一对可以发生反应的物质在一起时,吉丽知道它们的反应顺序。每次倾倒完后,吉丽会等到反应结束后再执行下一步骤。
吉丽想知道配置过程中总共产生多少沉淀。
\(n,m \leq 2 \times 10^5,k \leq 5 \times 10^5\)
分析
注意到初始状态下第i个瓶子里有物质i,也就是说每种物质恰好只在一个瓶子里。那么混合的过程中,每种反应至多发生一次。对于一个反应\((a,b)\),因为开始反应前只有1个瓶子里有a,1个瓶子里有b.而当a,b相遇时,会一直进行直到完全反应。
那么,我们只要知道第i个反应发生的时间,然后按时间给反应排序(时间相同时按优先级排序).然后一个个反应按顺序模拟,更新反应物的质量和沉淀质量。
如何求某个反应(a,b)发生的时间呢?。我们把处在同一个烧杯里的物质看成一个联通块,(a,b)发生的时间就是a和b最早连通的时间。用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与父亲相连。答案就是u到v路径上的点tim的最大值。具体参考[BZOJ 4668]冷战(并查集+启发式合并)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 200000
#define maxk 500000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
struct disjoint_set{
int fa[maxn+5];
int tim[maxn+5];
int sz[maxn+5];
int find(int x){
while(fa[x]!=x) x=fa[x];
return x;
}
int get_deep(int x){
int ans=0;
while(fa[x]!=x){
ans++;
x=fa[x];
}
return ans;
}
void merge(int x,int y,int t){
int fx=find(x);
int fy=find(y);
if(sz[fx]>sz[fy]) swap(fx,fy);
fa[fx]=fy;
tim[fx]=t;
sz[fy]+=sz[fx];
}
int query(int x,int y){
if(find(x)!=find(y)) return INF;
int ans=0;
int dx=get_deep(x),dy=get_deep(y);
if(dx<dy){
swap(x,y);
swap(dx,dy);
}
while(dx>dy){
ans=max(ans,tim[x]);
x=fa[x];
dx--;
}
if(x==y) return ans;
while(x!=y){
ans=max(ans,max(tim[x],tim[y]));
x=fa[x];
y=fa[y];
}
return ans;
}
void ini(int n){
for(int i=1;i<=n;i++){
fa[i]=i;
sz[i]=1;
}
}
}S;
int n,m,k;
int g[maxn+5];
struct rec{
int x;
int y;
int tim;
int id;
friend bool operator < (rec p,rec q){
if(p.tim==q.tim) return p.id<q.id;
else return p.tim<q.tim;
}
}q[maxk+5];
int main(){
int u,v;
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%d",&g[i]);
}
S.ini(n);
for(int i=1;i<=m;i++){
scanf("%d %d",&u,&v);
S.merge(u,v,i);
}
for(int i=1;i<=k;i++){
scanf("%d %d",&q[i].x,&q[i].y);
q[i].tim=S.query(q[i].x,q[i].y);
q[i].id=i;
}
sort(q+1,q+1+k);
ll ans=0;
for(int i=1;i<=k;i++){
if(q[i].tim==INF) continue;
int x=q[i].x,y=q[i].y;
int sum=min(g[x],g[y]);
g[x]-=sum;
g[y]-=sum;
ans+=sum*2;
}
printf("%lld\n",ans);
}
[HDU 3712] Fiolki (带边权并查集+启发式合并)的更多相关文章
- [BZOJ 4668]冷战(带边权并查集+启发式合并)
[BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...
- AcWing:240. 食物链(扩展域并查集 or 带边权并查集)
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形. A吃B, B吃C,C吃A. 现有N个动物,以1-N编号. 每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用 ...
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- BZOJ 4668: 冷战 并查集启发式合并/LCT
挺好想的,最简单的方法是并查集启发式合并,加暴力跳父亲. 然而,这个代码量比较小,比较好写,所以我写了 LCT,更具挑战性. #include <cstdio> #include < ...
- HDU-3038 How Many Answers Are Wrong(带权并查集区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3038 大致题意: 有一个区间[0,n],然后会给出你m个区间和,每次给出a,b,v,表示区间[a,b]的区间和为 ...
- POJ-1733 Parity game(带权并查集区间合并)
http://poj.org/problem?id=1733 题目描述 你和你的朋友玩一个游戏.你的朋友写下来一连串的0或者1.你选择一个连续的子序列然后问他,这个子序列包含1的个数是奇数还是偶数.你 ...
- BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)
http://www.lydsy.com/JudgeOnline/problem.php?id=3673 题意: 思路: 可持久化数组可以用可持久化线段树来实现,并查集的查询操作和原来的一般并查集操作 ...
- Codeforces 1166F 并查集 启发式合并
题意:给你一张无向图,无向图中每条边有颜色.有两种操作,一种是询问从x到y是否有双彩虹路,一种是在x到y之间添加一条颜色为z的边.双彩虹路是指:如果给这条路径的点编号,那么第i个点和第i - 1个点相 ...
随机推荐
- python导入不同目录下的自定义模块
一.代码目录结构 自定义的模块在Common包下,Study文件下SelectionSort.py文件导入自定义的模块 二.源码 2.1:SelectionSort.py文件 python导包默认 ...
- 【织梦手机端仿站】和PC一个后台
卸载插件,织梦默认带手机站,无需复杂使用插件以后不方便升级.织梦2015年6月8日更新后,就添加了很多针对手机移动端的设计,最大的设计就是添加了生成二维码的织梦标签和织梦手机模板功能,织梦更新后,默认 ...
- linux 系统时间 硬件时间
Linux时钟分为系统时钟(System Clock)和硬件时钟(Real Time Clock,简称RTC).系统时钟是指当前Linux Kernel中的时钟:而硬件时钟则是主板上由电池供电的时钟, ...
- JMS学习九(ActiveMQ的消息持久化到Mysql数据库)
1.将连接Mysql数据库的jar文件,放到ActiveMQ的lib目录下 2.修改ActiveMQ的conf目录下的active.xml文件,修改数据持久化的方式 2.1 修改原来的kshadb的 ...
- 关于Tomcat重启和关闭后重启session变化
,当页面第一次访问,session的attribute还未赋值,为null 当页面第二次访问时,这时当前的session的attribute有值了! 到了本文章的点题时刻!! 如果我是直接点击serv ...
- WOSA XFS 官方文档地址
WOSA XFS 官方文档地址: ftp://ftp.cencenelec.eu/CWA/CEN/WS-XFS/
- Oracle JET Model 数据获取与使用
Oracle JET 应用程序数据可以来自生成 JSON 数据的任何 Web 数据源,例如 REST 服务,服务器发送事件(SSE)或 WebSocket .此外,Oracle JET 还提供了基于 ...
- 流程控制 if else elif
[root@LV work]# [root@LV work]# vim name.py[root@LV work]# chmod +x name.py [root@LV work]# ./name.p ...
- js实现两个从input获取到的数字相加引发的问题
从input中获取到的数据是文本类型的,如果不转化类型直接相加会变成字符串的相加. 使用Number()函数可以解决这个问题,如下 var c = Number(a) + Number(b)
- centos设置定时删除文件定时清理网站日志
1.进入linux系统 2.在任意目录创建一个sh后缀的文件,如: 3.编辑打开该文件,如图: 4.此时按键盘上的“i”键或者“insert”键,进入编辑模式 输入: #!/bin/shfind /d ...