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
 */


posted @ 2016-12-15 15:58  Wasdns  阅读(175)  评论(0编辑  收藏  举报