acwing237. 程序自动分析(并查集应用)

题意

  1. 有 n 个变量:x1, x2, x3,…,xn , 现在我们要为每个变量赋一个值,使他们同时满足 m 个约束条件,
  2. 约束条件有两种形式:
    1. x i     =     x j x_i~~~=~~~x_j xi   =   xj
    2. x i     ! =     x j u x_i~~~!=~~~x_ju xi   !=   xju
  3. 如果能够满足输出 yes,否则输出 no

思路

  1. 我们用并查集为第一种形式的约束条件,并检查第二种条件是否都成立(即:与第一种约束条件所维护的集合发生冲突)。

代码

#include 
using namespace std;

const int N = 2e6 + 10;
int n, m, f[N];
unordered_map<int, int> mp;     //无序 插入查询更快!!!

struct Query
{
    int x, y, e;
} qu[N];

int get(int x)
{
    if (mp.count(x) == 0) mp[x] = ++ n;
    return mp[x];
}

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

int main()
{
    int T; scanf("%d", &T);
    while (T --)
    {
        mp.clear();
        n = 0;
        scanf("%d", &m);
        int x, y, e;
        for (int i = 0; i < m; i ++) {
            scanf("%d %d %d", &x, &y, &e);
            qu[i] = { get(x), get(y), e };
        }

        for (int i = 1; i <= n; i ++) f[i] = i;

        for (int i = 0; i < m; i ++) {
            if (qu[i].e)
            {
                x = find(qu[i].x), y = find(qu[i].y);
                f[x] = y;
            }
        }

        int flag = 1;
        for (int i = 0; i < m; i ++) {
            if (qu[i].e == 0)
            {
                x = find(qu[i].x), y = find(qu[i].y);
                if (x == y)
                {
                    flag = 0;
                    break;
                }
            }
        }

        if (flag) printf("YES\n");
        else printf("NO\n");
    }


    return 0;
}

你可能感兴趣的:(图论,算法)