51Nod-1515-明辨是非
2017-08-11 15:50
176 查看
ACM模版
描述
题解
这里主要涉及到相等和不相等以及不确定关系三种,初始化全部是不确定关系,通过 n 组操作对其进行修改,所有有效操作(YES)都会改变其不确定性关系,那么我们可以通过两种数据结构来表示这关系,相等的关系很容易想到,就是并查集,相等的我们并入一个并查集即可,那么不相等关系我们可以通过 set 来维护,这样我们就可以充分的表现任意两者之间的关系了。另外这里需要用到离散化,也就是用 map 打打标签,毕竟 x 和 y 都太大了。代码
#include <cstdio> #include <set> #include <map> using namespace std; const int MAXN = 2e5 + 10; int n, cnt = 1; int pre[MAXN]; set<int> si[MAXN]; map<int, int> mii; int find(int x) { return pre[x] == x ? x : pre[x] = find(pre[x]); } int main() { scanf("%d", &n); n <<= 1; for (int i = 1; i <= n; i++) { pre[i] = i; } n >>= 1; int x, y, p; while (n--) { scanf("%d%d%d", &x, &y, &p); if (mii[x]) { x = mii[x]; } else { x = mii[x] = ++cnt; } if (mii[y]) { y = mii[y]; } else { y = mii[y] = ++cnt; } int u = find(x), v = find(y); if (p == 1) { if (si[u].count(v)) // u 和 v 限制不相等 { puts("NO"); } else if (u != v) // 未限制但并未相等 { if (si[u].size() > si[v].size()) { swap(u, v); } pre[u] = v; for (auto it = si[u].begin(); it != si[u].end(); it++) { si[*it].insert(v); si[v].insert(*it); } puts("YES"); } else { puts("YES"); } } else { if (u == v) { puts("NO"); } else { si[u].insert(v); si[v].insert(u); puts("YES"); } } } return 0; }
相关文章推荐
- 51nod 1515 明辨是非 && 2017百度之星初赛第一场第二题(并查集+启发式合并)
- 51nod 1515 明辨是非 并查集 + set + 启发式合并
- 51nod 1515 明辨是非[并查集][set]
- 51nod 1515:明辨是非 并查集合并
- 51nod 1515:明辨是非 并查集合并
- 51nod 1515 明辨是非(合并并查集)
- 51nod 1515 明辨是非 启发式合并
- 51nod 1515 明辨是非[Waiting]
- 【51nod 1515】 明辨是非
- 【51Nod 1515】明辨是非
- [51Nod 1515] 明辨是非
- 51 nod 1515 明辨是非(并查集合并)
- 51nod 1040 最大公约数的和 欧拉函数
- 【51Nod-1008】N的阶乘 mod P
- 51nod 1434 理解lcm
- 51nod 1067 Bash游戏 V2
- 【dp基础课程】矩阵取数问题+最大子段和+最长公共子序列(LCS)【51nod】
- B - 好数 51Nod - 1717
- 【因子5的个数】1003 阶乘后面0的数量【51nod】
- 51nod 1675 序列变换 莫比乌斯反演(第二种形式)