UOJ14 DZY Loves Graph
DZY开始有 nn 个点,现在他对这 nn 个点进行了 mm 次操作,对于第 ii 个操作(从 11 开始编号)有可能的三种情况:
- Add a b: 表示在 aa 与 bb 之间连了一条长度为 ii 的边(注意,ii是操作编号)。保证 1≤a,b≤n1≤a,b≤n。
- Delete k: 表示删除了当前图中边权最大的k条边。保证 kk 一定不会比当前图中边的条数多。
- Return: 表示撤销第 i−1i−1 次操作。保证第 11 次操作不是 Return 且第 i−1i−1 次不是 Return 操作。
请你在每次操作后告诉DZY当前图的最小生成树边权和。如果最小生成树不存在则输出 00。
输入格式
第一行两个正整数 n,mn,m。表示有 nn 个点 mm 个操作。 接下来 mm 行每行描述一个操作。
输入格式
对于每一个操作输出一行一个整数表示当前最小生成树边权和。
样例一
input
2 2
Add 1 2
Return
output
1
0
样例二
input
5 10
Add 2 1
Add 3 2
Add 4 2
Add 5 2
Add 2 3
Return
Delete 1
Add 2 3
Add 5 2
Return
output
0
0
0
10
10
10
0
0
15
0
样例三
见样例数据下载
正解:并查集+各种奇怪维护
解题报告:
调试了两个多小时才AC,而且还蒯了别人的题解。
传送门:http://vfleaking.blog.uoj.ac/blog/15
我讲不太清楚,直接看vfk的博客吧。
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXM = ;
int n,m,cnt;//cnt统计树边
LL ans;
int father[MAXM],last[MAXM];//分别表示最小生成树中的所在块的祖先和这条边断掉之后的所在块的祖先(前提,这条边在最小生成树中)
//int stack[MAXM];
int size[MAXM],top;
char ch[];
LL num[MAXM];
vector<int>q;
struct ask{
int type,x,y;
}Q[MAXM]; inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} inline int find(int x){
if(father[x]!=x) return find(father[x]);
return father[x];
} inline void delet(int x){
int u;
while(x--) {
u=q[q.size()-]; q.pop_back();
//u=stack[top]; top--;
if(last[u]!=-) {
ans-=u; cnt--; int y=father[u];
while(y)
{
size[y]-=size[u];
if(y==father[y]) break;
}
//if(father[x]) size[father[x]]-=size[x];
father[last[u]]=last[u];
}
}
} inline void work(){
n=getint(); m=getint();
for(int i=;i<=m;i++) {
scanf("%s",ch);
if(ch[]=='A') Q[i].type=,Q[i].x=getint(),Q[i].y=getint();
else if(ch[]=='D') Q[i].type=,Q[i].x=getint();
else Q[i].type=;
}
for(int i=;i<=n;i++) father[i]=i,size[i]=;
int x,y;
for(int i=;i<=m;i++) {
if(Q[i].type==) {
//stack[++top]=i;
q.push_back(i);
x=find(Q[i].x); y=find(Q[i].y);
if(x!=y) {//加入最小生成树,后面的肯定不如前面的编号小的更优
if(size[x]>size[y]) swap(x,y);//交换,按秩
last[i]=x;
father[x]=y; size[y]+=size[x];
ans+=i; cnt++;
}
else last[i]=-;//不在最小生成树中
}
else if(Q[i].type==) {
if(Q[i+].type==) {
//printf("%lld\n",num[top-Q[i].x]);
printf("%lld\n",num[q.size()-Q[i].x]);
continue;
}else delet(Q[i].x);
}
else {
if(Q[i-].type==) delet();
} if(cnt==n-) {//构成最小生成树
//num[top]=ans;
num[q.size()]=ans;
printf("%lld\n",ans);
}
else {
//num[top]=0;
num[q.size()]=;
printf("0\n"); }
}
} int main()
{
work();
return ;
}
UOJ14 DZY Loves Graph的更多相关文章
- UOJ14 DZY Loves Graph 并查集
传送门 题意:给出一张$N$个点,最开始没有边的图,$M$次操作,操作为加入边(边权为当前的操作编号).删除前$K$大边.撤销前一次操作,每一次操作后询问最小生成树边权和.$N \leq 3 \tim ...
- 【UER #1】[UOJ#12]猜数 [UOJ#13]跳蚤OS [UOJ#14]DZY Loves Graph
[UOJ#12][UER #1]猜数 试题描述 这一天,小Y.小D.小C正在愉快地玩耍. 小Y是个数学家,他一拍脑袋冒出了一个神奇的完全平方数 n. 小D是个机灵鬼,很快从小Y嘴里套出了 n的值.然后 ...
- 学长小清新题表之UOJ 14.DZY Loves Graph
学长小清新题表之UOJ 14.DZY Loves Graph 题目描述 \(DZY\)开始有 \(n\) 个点,现在他对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 ...
- UOJ14 UER #1 DZY Loves Graph(最小生成树+并查集)
显然可以用可持久化并查集实现.考虑更简单的做法.如果没有撤销操作,用带撤销并查集暴力模拟即可,复杂度显然可以均摊.加上撤销操作,删除操作的复杂度不再能均摊,但注意到我们在删除时就可以知道他会不会被撤销 ...
- [UER #1] DZY Loves Graph
题目描述 开始有 \(n\) 个点,现在对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 \(1\) 开始编号)有可能的三种情况: \(Add\) a b: 表示在 \ ...
- uoj problem 14 DZY Loves Graph
题目: DZY开始有 \(n\) 个点,现在他对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 \(1\) 开始编号)有可能的三种情况: Add a b: 表示在 \( ...
- 【UER #1】DZY Loves Graph
UOJ小清新题表 题目内容 UOJ链接 DZY开始有\(n\)个点,现在他对这\(n\)个点进行了\(m\)次操作,对于第\(i\)个操作(从\(1\)开始编号)有可能的三种情况: Add a b: ...
- 【UOJ #14】【UER #1】DZY Loves Graph
http://uoj.ac/problem/14 题解很好的~ 不带路径压缩的并查集能保留树的原本形态. 按秩合并并查集可以不用路径压缩,但是因为此题要删除,如果把深度当为秩的话不好更新秩的值,所以把 ...
- 【UER #1】DZY Loves Graph(待卡常数)
题解: 正解是可持久化并查集 但这个显然是lct可以维护的 但这常数是个问题啊??? #include <bits/stdc++.h> using namespace std; struc ...
随机推荐
- 【BZOJ2819】Nim 树状数组+LCA
[BZOJ2819]Nim Description 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可 ...
- eval()和exec()函数的区别
(1)eval(str [,globals [,locals ])函数将字符串str当成有效Python表达式来求值,并返回计算结果.(2)exec()函数将字符串str当成有效的Python表达式来 ...
- Introduction to Mathematical Thinking - Week 3
there exists and all there exists 证明根号2是无理数 all 习题 3. Which of the following formal propositions say ...
- 2048 worker_connections are not enough while connecting to upstream
2048 worker_connections are not enough while connecting to upstream http://mailman.nginx.org/piperma ...
- WIN文件放到LINUX中无法CAT过滤的解决方法
有个WIN文件放到LINUX服务器上处理的时候,由于编码的问题,导致无法过滤,此时需要对文件进行处理 cat file | tr -s "\r" "\n" &g ...
- 浅析TCP/IP
TCP/IP概述 TCP/IP起源于1969年美国国防部(DOD:The United States Department Of Defense)高级研究项目管理局(APRA:AdvancedRese ...
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related(转)
转至:http://www.cnblogs.com/taoys/archive/2010/12/30/1922186.html application/x-www-form-urlencoded: 窗 ...
- (扫盲)C#中out和ref之间的区别
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...
- javascript;select动态添加和删除option
<select id="sltCity"></select> //添加Option. var optionObj = new Option(text, va ...
- STM32探秘 之FSMC
源:STM32探秘 之FSMC STM32 FSMC总线深入研究