源哥每日一题第十八弹 poj 1182 并查集

题目链接:http://poj.org/problem?id=1182

题意:看不懂?退群吧

比平常的并查集加了一个判断集合间关系的操作;

开一个数组记录当前点所在集合的次序(第几个集合)用012表示

比较简单的思路,不过体现了并查集的精妙

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
int dad[500005];
int st[50005];
int find(int x) {
    if(dad[x] != x) {
        int t = dad[x];
        dad[x] = find(t);
        st[x] += st[t];
        st[x] %= 3;
    }
    return dad[x];
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("D:\\fengyu\\Jiang_C\\.vscode\\in.txt","r",stdin);
	freopen("D:\\fengyu\\Jiang_C\\.vscode\\out.txt","w",stdout);
#endif
    int n, k;
    cin >> n >> k;
    for (int i = 0; i <= n; i++) {
        dad[i] = i;
        st[i] = 0;
    }
    int d, x, y;
    int ans = 0;
    while (k--) {
        scanf("%d%d%d", &d, &x, &y);
        if (x>n|| y>n || d==2 && x==y) {
            ans++;
            continue;
        }
        int fx = find(x);
        int fy = find(y);
        if(fx==fy) {
            if(d==1 && st[x]!=st[y] || d==2 &&st[x]!=(st[y]+2)%3) {
                ans++;
            }
        } else {
            dad[fy] = fx;
            st[fy] = (st[x]+d-1+3-st[y])%3;
        }
    }
    cout << ans << endl;

    return 0;
}

  

原文地址:https://www.cnblogs.com/fengyuzhicheng/p/9185412.html

时间: 2024-10-13 16:04:56

源哥每日一题第十八弹 poj 1182 并查集的相关文章

源哥每日一题第十九弹 poj 2236 还是冰茶集

连接:http://poj.org/problem?id=2236 题意:有一堆坏电脑,和两种操作:O表示修好这台电脑,S 询问两台电脑是否联通.主要是判电脑是否联通:两台电脑间距离小于d就是联通的. 题解:emmm--直接写啊 #include <iostream> #include <cstdio> using namespace std; int n; long long d; int pre[1005]; int jud[1005]; struct coor { long

源哥每日一题第十四弹 hdu 1565 还是状压dp

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意:自己念 分析:有了上一题的基础,这题的状态方程也好想:dp[i][s]表示第i行第s个状态取得的最大值. 可以预处理出每一行每一种状态所能获得的值,方程就是dp[i][j] = max(dp[i][j],dp[i-1][k]+sum[i][j]); 要注意的就是判断相邻的情况:两个状态,如果a&b!=0则表示它们有相重叠的区域. #include <bits/stdc++.h> u

源哥每日一题第十三弹 百练4124:海贼王之伟大航路 状压dp

连接:http://bailian.openjudge.cn/practice/4124 题意:从1到n走过所有点恰好一次最短时间.乱搞的话会完美的超时(阶乘级别的复杂度,虽然范围很小,但是也足够超时了). 思路:先想一个不太成熟的思路.用dp[s][j]表示.s记录的是每个点是否被走过的状态.而dp[s][j]表示的是从1走到j状态所用的最小时间.这样的思路成不成立呢?首先,考虑初始值.开始是在1号点,那么dp[1][1]自然就是0了,其他就是max:另外,题面说只要遍历每一个点,而于顺序的话

源哥每日一题第20弹 poj 1272 还是冰茶集

连接:http://acm.hdu.edu.cn/showproblem.php?pid=1272 题意:要 要 要 要啥题意啊就是问题这个东西是不是一颗树 解决方式有很多种,说是冰茶集,但是你用别的方法也可以做啊~ 思路:首先作为一棵树一定满足顶点数等于边数+1,但只满足了这个条件也不行(脑补一个圆)判断方法:比方说a和b俩节点,他俩爹要是一样,你再把a和b连上,那不就有环了吗 p.s. 我记得这个题在hdu上会爆栈来着-- 还想硬广一下 #pragma comment(linker, "/S

每日算法之二十八:Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2. Another example is &

跟着chengyulala刷题之[kuangbin带你飞]之&#39;并查集&#39;专题/斜眼笑

[kuangbin带你飞] 专题1-23 https://vjudge.net/article/187 专题五 并查集 POJ 2236 Wireless Network  http://poj.org/problem?id=2236POJ 1611 The Suspects  http://poj.org/problem?id=1611HDU 1213 How Many Tables  http://acm.hdu.edu.cn/showproblem.php?pid=1213HDU 3038

CodeVS2492 上帝造题的七分钟2(树状数组+并查集)

传送门 树状数组模板题.注意优化,假设某个数的值已经是1了的话.那么我们以后就不用对他进行操作了,这个能够用并查集实现. 这道题还有个坑的地方,给出查询区间端点的a,b,有可能a>b. #include<cstdio> #include<cmath> #include<cctype> #include<iostream> using namespace std; inline void GET(int &t){ char c; t=0; do{

每天刷个算法题20160522:支持各种类型的并查集

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524671 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

Redis源码剖析和注释(十八)--- Redis AOF持久化机制

Redis AOF持久化机制 1. AOF持久化介绍 Redis中支持RDB和AOF这两种持久化机制,目的都是避免因进程退出,造成的数据丢失问题. RDB持久化:把当前进程数据生成时间点快照(point-in-time snapshot)保存到硬盘的过程,避免数据意外丢失. AOF持久化:以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的. Redis RDB持久化机制源码剖析和注释 AOF的使用:在redis.conf配置文件中,将appendonly设置为y