HDU 2419 Boring Game(并查集+map)
感觉做得有点复杂了,但是AC了还是。。。爽。。。
题意:给你n个点每个点有一个价值,接下来有m条边,然后是q个操作,每个操作有三种情况:
F X K:寻找与X点直接或间接相连的不小于价值K的最小价值,如果找不到就是0
U X K:将X点价值变为K
E A B:删除点A与点B形成的边
最后求价值总和的平均值
首先我们看F操作和U操作可以使用map解决,因为这是典型的带修改并区间找寻大于等于某值的最小值。然后我们看删边,如果直接删的话,我们需要遍历这一维map然后拆分,时间过不了。因此我们想到使用离线操作倒序添边,然后处理集合合并问题就是并查集的典型题了。
接着我们离线后要把每个E与U都处理后再添边,对于U我们必须保存所有修改的历史,因此使用vector。而m条边中删除E的边,我们需要节约时间。存下总所有边与需要删除的边,然后一起排序后双指针维护添边(因为需要删除的边一定在所有边中出现过,且没有重边)。接着对于维护E,添边后需要把一个父节点并上去,且两个map也要合并,因此我们为了节约合并时间,需要简单的启发式合并。其实就是并查集合并时把个数少的并到个数多的上面。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
struct node
{
char typ[];
int u,v;
}add[Max],del[Max],ope[Max];
int fat[Max],ran[Max];//离线添边的并查集
map<int,int> mp[Max];//祖先形成的集合里的元素
vector<int> vec[Max];//存下修改的过程值
int len[Max];
void Init(int n)
{
for(int i=;i<n;++i)
{
ran[i]=;
len[i]=;
vec[i].clear();
mp[i].clear();
fat[i]=i;
}
return;
}
int Find(int x)
{
if(x==fat[x])
return fat[x];
return fat[x]=Find(fat[x]);
}
void UnMap(int x1,int y1)
{
for(map<int,int>::iterator it=mp[x1].begin();it!=mp[x1].end();)
{
if(!mp[y1].count(it->first))
mp[y1][it->first]=it->second;
else
mp[y1][it->first]+=it->second;
mp[x1].erase(it++);//删除
}
return;
}
void Union(int x,int y)
{
int x1=Find(x);
int y1=Find(y);
if(x1==y1)
return;
if(ran[x1]<ran[y1])
{
fat[x1]=y1;//价值合并
ran[y1]+=ran[x1];
UnMap(x1,y1);
}
else
{
fat[y1]=x1;//价值合并
ran[x1]+=ran[y1];
UnMap(y1,x1);
}
return;
}
bool cmp(struct node p1,struct node p2)
{
if(p1.u==p2.u)
return p1.v<p2.v;
return p1.u<p2.u;
}
map<int,int>::iterator it;
double Solve(int n,int m,int q,int cnt,int dig)
{
int coun=;
double ans=0.0;
for(int i=;i<n;++i)
mp[i][vec[i][len[i]]]=;//开始每个集合是自己
sort(add,add+m,cmp);
sort(del,del+cnt,cmp);
del[cnt].u=del[cnt].v=-;
//for(int i=0;i<m;++i)
// printf("%d %d\n",add[i].u,add[i].v);
// printf("OK\n");
// for(int i=0;i<cnt;++i)
//printf("%d %d\n",del[i].u,del[i].v);
for(int i=;i<m;++i)//初始添边
{
if(add[i].u==del[coun].u&&add[i].v==del[coun].v)//两边排序后双指针维护
coun++;
else
{//printf("OK\n");
Union(add[i].u,add[i].v);
}
}
for(int i=q-;i>=;--i)
{
if(ope[i].typ[]=='F')
{
int x1=Find(ope[i].u);
it=mp[x1].lower_bound(ope[i].v);
if(it==mp[x1].end())
ans+=0.0;
else
ans+=it->first;
}
else if(ope[i].typ[]=='E')
Union(ope[i].u,ope[i].v);
else//换价值
{
int x1=Find(ope[i].u);
mp[x1][ope[i].v]--;
if(mp[x1][ope[i].v]==)
mp[x1].erase(ope[i].v);
if(mp[x1].count(vec[ope[i].u][len[ope[i].u]-]))
mp[x1][vec[ope[i].u][--len[ope[i].u]]]++;
else
mp[x1][vec[ope[i].u][--len[ope[i].u]]]=;
}
}//printf("%d\n",dig);
return ans/dig;
}
int main()
{
int n,m,q;
int u,v,c;
int cnt,dig,coun=;
while(~scanf("%d %d %d",&n,&m,&q))
{
Init(n);
dig=cnt=;
for(int i=;i<n;++i)
{
scanf("%d",&c);
vec[i].push_back(c);
}
for(int i=;i<m;++i)
{
scanf("%d %d",&u,&v);
u--,v--;
if(u>v)
swap(u,v);
add[i].u=u;
add[i].v=v;
}
for(int i=;i<q;++i)
{
scanf("%s %d %d",&ope[i].typ,&ope[i].u,&ope[i].v);
if(ope[i].typ[]=='F')
{
dig++;
ope[i].u--;
}
else if(ope[i].typ[]=='E')
{
ope[i].u--,ope[i].v--;
if(ope[i].u>ope[i].v)
swap(ope[i].u,ope[i].v);
del[cnt].u=ope[i].u,del[cnt++].v=ope[i].v;
}
else
{
ope[i].u--;
len[ope[i].u]++;
vec[ope[i].u].push_back(ope[i].v);
}
}
printf("Case %d: %.3f\n",++coun,Solve(n,m,q,cnt,dig));
Init(n);
}
return ;
}
HDU 2419 Boring Game(并查集+map)的更多相关文章
- HDU 1811 拓扑排序 并查集
有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的. 相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0 ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- HDU(3560)成环,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3560 并查集查有几个块,修改了之前我的一个方法(用什么map),直接判断根节点的id是i的个数. 然后 ...
- HDU 2473 Junk-Mail Filter 并查集,虚拟删除操作
http://acm.hdu.edu.cn/showproblem.php?pid=2473 给定两种操作 第一种是合并X Y 第二种是把X分离出来,就是从原来的集合中分离出来,其它的关系不变. 关键 ...
- HDU 2473 Junk-Mail Filter(并查集的删除操作)
题目地址:pid=2473">HDU 2473 这题曾经碰到过,没做出来. .如今又做了做,还是没做出来. ... 这题涉及到并查集的删除操作.想到了设一个虚节点,可是我把虚节点设为了 ...
- HDU 5441 离线处理 + 并查集
题意:给n个节点m条带权值边的无向图.然后q个问题,每次询问点对的数目,点对需要满足的条件是:1)连通:2)其路径的最大权值不能超过询问值. 分析:如果没次询问一次,dfs一次,很可能超时,因此可以用 ...
- HDU 4496 D-City (并查集)
题意:有n个城市,m条路,首先m条路都连上,接着输出m行,第i行代表删除前i行的得到的连通块个数 题解:正难则反,我们反向考虑使用并查集添边.首先每个点都没有相连,接着倒着来边添加边计算,当两个点父节 ...
- HDU 5441 Travel (并查集+数学+计数)
题意:给你一个带权的无向图,然后q(q≤5000)次询问,问有多少对城市(城市对(u,v)与(v,u)算不同的城市对,而且u≠v)之间的边的长度不超过d(如果城市u到城市v途经城市w, 那么需要城市u ...
- hdu 2480 贪心+简单并查集
Steal the Treasure Time Limit: 10000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
随机推荐
- 1878: [SDOI2009]HH的项链
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 4420 Solved: 2199[Submit][Statu ...
- SpringBoot自带热加载开发工具
SpringBoot自带热加载开发工具 maven配置: <!-- SpringBoot自带热加载开发工具 --> <dependency> <groupId>or ...
- php自定义函数: 改进升级版curl
<?php function dcurl($url, $method = 'GET', $postFields = null, $header = null) { $ch = curl_init ...
- 【转】Power System 中基于 VIOS 的虚拟以太网实现
基于 VIOS 的虚拟以太网适配器的工作原理和配置实现 本文对 Power 系统中基于 VIOS 的虚拟以太网适配器(Virtual Ethernet Adapter)的工作原理.基本配置选项和配置步 ...
- angular2表单初体验
1.创建movie模型. 最近对angular2比较感兴趣,跟着官网学习一段,练习了一个表单demo! src/app/movie.ts文件: export class Movie{ construc ...
- 全面Python小抄(转)
add by zhj: 有些地方不正确,有时间再改吧 原文:Python Cheat Sheet Cheat sheet of Python. Some basic concepts for Pyth ...
- Linux python3安装/shell脚本/if/循环/函数
python3安装 安装过程 安装包: wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgztar -xvf Python-3.7 ...
- 我的Android进阶之旅------>HTTP Content-type 对照表
HTTP Content-type 对照表 文件扩展名 Content-Type(Mime-Type) 文件扩展名 Content-Type(Mime-Type) .*( 二进制流, 不知道下载文件类 ...
- LATEX教程(二)
插入图片 \documentclass{article} \usepackage{graphicx} \usepackage{Ctex} \title{插入图片} \author{yif} \begi ...
- ASP.NET MVC string赋值Html格式在显示View问题总结
ViewBag.Content = "<p>你好</p>"; string 类型的赋值一个 "<h1>你好</h1>&qu ...