NOJ 1044 连通 OR 不连通 (离线并查集 + hash)
来源:互联网 发布:java后端开发做什么的 编辑:程序博客网 时间:2024/05/16 05:44
连通 OR 不连通
时间限制(普通/Java) :1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 333 测试通过 : 65
题目描述
给定一个无向图,一共n个点,请编写一个程序实现两种操作:
D x y 从原图中删除连接x,y节点的边。
Q x y 询问x,y节点是否连通
输入
第一行两个数n,m(5<=n<=40000,1<=m<=100000)
接下来m行,每行一对整数 x y (x,y<=n),表示x,y之间有边相连。保证没有重复的边。
接下来一行一个整数 q(q<=100000)
以下q行每行一种操作,保证不会有非法删除。
输出
按询问次序输出所有Q操作的回答,连通的回答C,不连通的回答D
样例输入
3 3
1 2
1 3
2 3
5
Q 1 2
D 1 2
Q 1 2
D 3 2
Q 1 2
样例输出
C
C
D
题目链接:http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1044
题目分析:因为删边操作比较麻烦,而且这题的数据量比较大,如果是单纯的判连通,我们可以用普通并查集来做,我们可以把删边操作转化为添边操作,方法很简单,反向操作就可以了,开始先将不用被删的边加入并查集(这里需要用到hash,记录一下所有要被删的边),遇到D x y则将其合并,理由很简单,因为在删除它们之前它们是连通的,例如样例,我们先记录下所有输入数据,然后从Q 1 2开始,因为不需要删除的点已经被我们合并,D 3 2时合并 3 2,很显然在D 3 2上面的状态下它们还是相连的,最后用一个数组存储答案,因为是反向操作的,答案数组的输出也得反着输。
#include <cstdio>#include <cstring>#include <map>#include <algorithm>using namespace std;int const MAX = 100005;int n, m, fa[MAX];char ans[MAX];struct EDGE{ int u, v; bool d;}e[MAX], q[MAX];map<int, bool> hash;void UF_set(){ for(int i = 0; i <= MAX; i++) fa[i] = i;}int Find(int x){ return x == fa[x] ? x : fa[x] = Find(fa[x]);}void Union(int a, int b){ int r1 = Find(a); int r2 = Find(b); if(r1 != r2) fa[r2] = r1;}int main(){ UF_set(); scanf("%d %d", &n, &m); for(int i = 0; i < m; i++) { scanf("%d %d", &e[i].u, &e[i].v); if(e[i].u > e[i].v) swap(e[i].u, e[i].v); } int qnum; char s[2]; scanf("%d", &qnum); for(int i = 0; i < qnum; i++) { scanf("%s %d %d", s, &q[i].u, &q[i].v); if(q[i].u > q[i].v) swap(q[i].u, q[i].v); if(s[0] == 'D') { q[i].d = true; hash[q[i].u * MAX + q[i].v] = true; } else q[i].d = false; } for(int i = 0; i < m; i++) if(!hash[e[i].u * MAX + e[i].v]) Union(e[i].u, e[i].v); int cnt = 0; for(int i = qnum - 1; i >= 0; i--) { if(q[i].d) Union(q[i].u, q[i].v); else { if(Find(q[i].u) == Find(q[i].v)) ans[cnt++] = 'C'; else ans[cnt++] = 'D'; } } for(int i = cnt - 1; i >= 0; i--) printf("%c\n", ans[i]);}
- Oracle 阻塞会话的查看与解除
- Java I/O
- 最短路径(二)—Dijkstra算法(通过边实现松弛:邻接矩阵)
- java自带线程池和队列详细讲解
- IPMI的配置及常规功能
- NOJ 1044 连通 OR 不连通 (离线并查集 + hash)
- 如何分析Android的Log
- vim之一--vim介绍【转载】
- Linux 下小米WIFI 的无线网卡驱动
- Android之ContentProvider总结
- VI/VIM提示没有权限保存时的解决方法
- Extjs 动态加载机制研究
- 【C++ Primer】【学习笔记】【第八章】标准IO库之:字符串流
- 在卡内基梅隆大学 (Carnegie Mellon University) 就读是怎样一番体验?——Lina