• DS实验题 Old_Driver UnionFindSet结构


    题目

    思路

    很典型的并查集问题,朋友A和B要合并到一个统一的集合中,也就是Union(A, B)操作,在Union操作中需要先找到A所属的集合的代表元和B所属集合的代表元,也就是使用Find(A)和Find(B),如果它们的代表元不一样,则将B集合合并到A集合(pre[B_root] = A_root)。

    在Find的过程中,使用了路径压缩算法,使用i记录当前节点,使用j记录当前i的上级:
    1.用j记录i的上级 2.将i的上级改为i_root 3.i=j

    本题中,另外一种关系,也就是敌人,可以用一个二维数组存储,或者用邻接表存储都可以。

    代码:

    //
    //  main.cpp
    //  UnionFindSet
    //
    //  Created by wasdns on 16/12/15.
    //  Copyright © 2016年 wasdns. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int pre[1000];
    
    int rela[105][105];
    
    void Initial(int n)
    {
        memset(pre, 0, sizeof(pre));
        memset(rela, 0, sizeof(rela));
        
        for (int i = 1; i <= n; i++)
        {
            pre[i] = i;
        }
    }
    
    int Find(int a)
    {
        int fa = a;
        
        while (fa != pre[fa])
        {
            fa = pre[fa];
        }
        
        int i = a, j;
        
        while (i != fa)     //路径压缩算法。
        {
            j = pre[i];     //记录上级
            pre[i] = fa;    //修改当前上级为root
            i = j;          //来到原来的上级
        }
        
        return fa;
    }
    
    void Union(int a, int b)
    {
        int afa = Find(a);
        int bfa = Find(b);
        
        if (afa != bfa)
        {
            pre[bfa] = afa; //b所属集合的名字,改为a所属集合的名字
        }
    }
    
    void CreatRela(int m)
    {
        int i;
        
        int x, y, r;
        
        for (i = 1; i <= m; i++)
        {
            cin >> x >> y >> r;
            
            if (r == 1) Union(x, y);
            
            else if (r == -1) {
                
                rela[x][y] = -1;
                
                rela[y][x] = -1;
            }
        }
    }
    
    void Query(int k)
    {
        int i;
        
        int x, y;
        
        for (i = 1; i <= k; i++)
        {
            cin >> x >> y;
            
            if (rela[x][y] == 0)
            {
                if (Find(x) == Find(y)) {
                    cout << "Good job" << endl;
                }
                
                else {
                    cout << "No problem" << endl;
                }
            }
            
            else
            {
                if (Find(x) == Find(y)) {
                    cout << "OK but..." << endl;
                }
                
                else {
                    cout << "No way" << endl;
                }
            }
        }
    }
    
    int main()
    {
        int n, m, k;
        
        cin >> n >> m >> k;
        
        Initial(n);
        
        CreatRela(m);
        
        Query(k);
        
        return 0;
    }
    
    /*
     7 8 4
     5 6 1
     2 7 -1
     1 3 1
     3 4 1
     6 7 -1
     1 2 1
     1 4 1
     2 3 -1
     */
    
    
    
  • 相关阅读:
    CodeForces 757C Felicity is Coming!(排列组合)
    Ural 1519 Formula 1( 插头dp )
    FZU 2187 回家种地 ( 扫描线 + 离散 求矩阵单次覆盖面积 )
    HDU 1255 覆盖的面积 ( 扫描线 + 离散 求矩阵大于k次面积并 )
    ZOJ 3841 Cards
    HDU 4012 Paint on a Wall(状压+bfs)
    Topcoder SRM653div2
    2015 GDUT校赛
    Topcoder SRM652div2
    CodeChef A String Game(SG)
  • 原文地址:https://www.cnblogs.com/qq952693358/p/6183609.html
Copyright © 2020-2023  润新知