博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P1196 银河英雄传说
阅读量:6295 次
发布时间:2019-06-22

本文共 1357 字,大约阅读时间需要 4 分钟。

大意:你有30000个队列,第i个队列中只有i

有T个操作,1,把某个队列头接到另一个队列尾。

2,问两个元素之间的距离。

本题主要有三种解法。

①带权并查集。

具体来说就是,并查集维护当前集合的大小,这个点距离代表元(队首)的边数。

然后把合并和路径压缩魔改一下。询问的时候就直接取距离之差。

1 #include 
2 3 const int N = 30010; 4 5 int fa[N], sum[N], siz[N]; 6 char str[5]; 7 8 inline int find(int x, int &s) { 9 if(fa[x] == x) {10 s = 0;11 return x;12 }13 int t = find(fa[x], s);14 s += sum[x];15 sum[x] = s;16 return fa[x] = t;17 }18 19 inline void merge(int x, int y) {20 int a, b;21 x = find(x, a);22 y = find(y, b);23 fa[x] = y;24 sum[x] = siz[y];25 siz[y] += siz[x];26 return;27 }28 29 inline int ask(int x, int y) {30 int a, b;31 x = find(x, a);32 y = find(y, b);33 if(x != y) {34 return -1;35 }36 return (a > b ? a - b : b - a) - 1;37 }38 39 int main() {40 int n;41 scanf("%d", &n);42 for(int i = 1; i <= 30000; i++) {43 fa[i] = i;44 siz[i] = 1;45 }46 for(int i = 1, x, y; i <= n; i++) {47 scanf("%s%d%d", str, &x, &y);48 if(str[0] == 'M') {49 merge(x, y);50 }51 else {52 printf("%d\n", ask(x, y));53 }54 }55 56 return 0;57 }
AC代码

②平衡树

这个太暴力了......开30000颗平衡树即可。

③离线(kruskal重构树)

重构的时候把顺序搞一下,然后提出来DFS序,直接回答询问。

 

转载于:https://www.cnblogs.com/huyufeifei/p/10013449.html

你可能感兴趣的文章
php--------获取当前时间、时间戳
查看>>
Spring MVC中文文档翻译发布
查看>>
docker centos环境部署tomcat
查看>>
JavaScript 基础(九): 条件 语句
查看>>
Linux系统固定IP配置
查看>>
配置Quartz
查看>>
Linux 线程实现机制分析
查看>>
继承自ActionBarActivity的activity的activity theme问题
查看>>
设计模式01:简单工厂模式
查看>>
项目经理笔记一
查看>>
Hibernate一对一外键双向关联
查看>>
mac pro 入手,php环境配置总结
查看>>
MyBatis-Plus | 最简单的查询操作教程(Lambda)
查看>>
rpmfusion 的国内大学 NEU 源配置
查看>>
spring jpa 配置详解
查看>>
IOE,为什么去IOE?
查看>>
Storm中的Worker
查看>>
dangdang.ddframe.job中页面修改表达式后进行检查
查看>>
Web基础架构:负载均衡和LVS
查看>>
Linux下c/c++相对路径动态库的生成与使用
查看>>