并查集......

暂时只能想起这么几个题.......

A  parity game

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>

using namespace std;

const int N = 10010;

int n, m, cnt;
int p[N], d[N];
unordered_map<int, int> S;
// 离散化
int get(int x)
{
    if (S.count(x) == 0) S[x] = ++ cnt;
    return S[x];
}

int find(int x)
{
    if (x != p[x])
    {
        int root = find(p[x]);//找到树根节点
        d[x] ^= d[p[x]];// 节点x与到树根节点上的每个节点都相与。
        p[x] = root;
    }
    return p[x];
}

int main()
{
    S.clear();
    scanf("%d%d", &n, &m);
    
    for (int i = 0; i <= N; i ++) p[i] = i;
    
    int res = m;
    
    for (int i = 0; i < m; i ++)
    {
        int x, y, t;
        char s[5];
        scanf("%d%d%s", &x, &y, s);
        // 注意是次数是x-1, 联想前缀和,(S[y] - S[x - 1])
        x = get(x - 1), y = get(y);
        t = s[0] == 'o';
        int px = find(x), py = find(y);
        // 如果属于同一个集合
        if (px == py)
        {
            if ((d[x] ^ d[y]) != t) //奇偶性与答案不一致就break
            {
                res = i;
                break;
            }
        } else {
             p[px] = py;
             d[px] = d[x] ^ d[y] ^ t; //此处是根据 t = d[x] ^ d[y] ^ d[px]推导而来
        }
        
    }
    printf("%d\n", res);
    
    return 0;
}

B 矩形

#include<bits/stdc++.h>
using namespace std ;
const int N = 1e6 + 10 , M = 1e5 ;
int n ;
int p[N] , cnt1[N] , cnt2[N] ;

int find(int x)
{
    if(x != p[x]) p[x] = find(p[x]) ;
    return p[x] ;
}

int main()
{
    cin >> n ;
    for(int i = 1 ; i <= N - 10 ; i ++) p[i] = i ;
    
    for(int i = 1 ; i <= n ; i ++)
    {
        int x , y ;
        scanf("%d %d",&x , &y) ;
        p[find(x)] = find(y + M) ;
    }
    
    for(int i = 1 ; i <= M ; i ++) cnt1[find(i)] ++ ;
    for(int i = M + 1 ; i <= 2 * M ; i ++) cnt2[find(i)] ++ ;
    
    long long res = 0 ;
    for(int i = 1 ; i <= 2 * M ; i ++) res += (long long)cnt1[i] * cnt2[i] ;
    
    cout << res - n ;
    return 0 ;
}

C    Ladder Takahashi

https://atcoder.jp/contests/abc277/tasks/abc277_c

这个题多种写法,链式前向星或者并查集都可

C相比AB就没啥思维难度了

D Do use hexagon grid

https://atcoder.jp/contests/abc269/tasks/abc269_d

用并查集可以倒是可以但是好像....???是不是写的太麻烦了?

E 判环

const int N=1e6+10;
int p[N];
int find(int x){
    if(p[x]!=x)  p[x]=find(p[x]);
    return p[x];
}
 
signed main(){
    int n,m;
    while(cin>>n>>m){
        if(!n && !m) break;
        fer(i,1,n) p[i]=i;
        bool fl=false;
        fer(i,1,m){
            int a,b;
            cin>>a>>b;
            if(find(a)!=find(b)){
                p[find(a)]=find(b);
            }
            else{
                fl=1;
                break;
            }
        }
        if(fl){
            cout<<"YES\n";
        }
        else{
            cout<<"NO\n";
        }
    }
}

abc的285的D - Change Usernames和这个就基本一模一样了(当然也有别的写法),纯板题

https://atcoder.jp/contests/abc285/tasks/abc285_d

#include <bits/stdc++.h>
using namespace std;
unordered_map<string, int>S;
int cnt;
const int N = 1e6;
int p[N];

int get(string x) {
    if (S.count(x) == 0)
        S[x] = ++cnt;
    return S[x];
}

int find(int x) {
    if (p[x] != x)
        p[x] = find(p[x]);
    return p[x];
}

int merge(int x, int y) {
    int fx = find(x);
    //cout << fx << " ";
    int fy = find(y);
    //cout << fy << endl;
    if (fx == fy)
        return 1;

    p[fx] = fy;
    return 0;
}

int main() {
    int n;
    cin >> n;
    for (int i = 1; i < N; i++) {
        p[i] = i;
    }
    while (n--) {
        string s, t;
        cin >> s >> t;
        int u = get(s);
        int o = get(t);
        //cout << u << " " << o << endl;
        if (merge(u, o)) {
            cout << "No" << endl;
            return 0;
        }
    }
    cout << "Yes" << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值