UESTC 1586 可以说是非常豹笑了 2-SAT+并查集

来源:互联网 发布:淘宝店铺动态怎么写 编辑:程序博客网 时间:2024/05/16 01:42

可以说是非常豹笑了

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)


Submit  Status
title


你总是说:“可以说是非常豹笑了”


可是非常豹已经很累了,


非常豹不想笑,


它想念自己的家人,


而不是被你逼着笑。


你关心过这些吗?


没有!你只关心你自己。


Input

第一行输入一个正整数N(2<=N<=1000000)表示总天数,一个正整数M(1<=M<=1000000)表示给出的关系数。


接下来M行,每行三个整数T(T=1 or 0)、A、B(1<=A,B<=N)。T=1表示在第A天和第B天非常豹的表情一样、T=0表示在第A天和第B天非常豹的表情不一样。


非常豹在一天里要么笑了,要么没笑。


Output

输出 'YES’ 如果输入是可能的话;


输出'NO' 如果无论怎样都不可能满足输入给出的关系。


Sample input and output

Sample Input Sample Output
2 2
1 1 2
0 2 1
NO
2 2
1 1 1
0 2 1
YES


Hint

没有多组数据


Source

2017 UESTC Training for Data Structures

UESTC 1586 可以说是非常豹笑了


My Solution

题意:n个数,m个关系,每个关系表示T==1则a、b两数相同,T == 0则a、b两数不同。
要求判断关系是否没有矛盾。


2-SAT+并查集
有一个大小为2*n的并查集,
如果a、b天相同,则把a和b,以及a+n和b+n,合并,
如果a、b天不同,则把a和b+n,以及a+n和b,合并,
然后i= 1 ~ n,扫一遍,如果 a和a+n在同一颗树中,则相矛盾,
因为不可能那天表情即一样又不一样,答案为NO,
反正为 YES
复杂度 O(2*n)


#include <iostream>#include <cstdio>using namespace std;typedef long long LL;const int MAXN = 1e6 + 8;int father[2*MAXN], _rank[2*MAXN];inline void init(int n){    for(int i = 0; i <= n; i++){        father[i] = i;        _rank[i] = 0;    }}inline int _find(int x){    return father[x] = father[x] == x ? x : _find(father[x]);}inline void _merge(int x, int y){    int a = _find(x), b = _find(y);    if(a == b) return;    else{        if(_rank[a] < _rank[b]){            father[a] = b;        }        else{            father[b] = a;            if(_rank[a] == _rank[b]){                _rank[a]++;            }        }    }}int main(){    #ifdef LOCAL    freopen("n.txt", "r", stdin);    //freopen("n.out", "w", stdout);    int T = 2;    while(T--){    #endif // LOCAL    //ios::sync_with_stdio(false); cin.tie(0);    int n, m, i, j, t, x, y;    scanf("%d%d", &n, &m);    init(2*n);    for(i = 1; i <= m; i++){        scanf("%d%d%d", &t, &x, &y);        if(t){            _merge(x, y);            _merge(x + n, y + n);        }        else{            _merge(x, y + n);            _merge(x + n, y);        }    }    bool ans = true;    for(i = 1; i <= n; i++){        if(_find(i) == _find(i + n)){            ans = false;            break;        }    }    if(ans) puts("YES");    else puts("NO");    #ifdef LOCAL    cout << endl;    }    #endif // LOCAL    return 0;}


  Thank you!

                                                                                                                                             ------from ProLights

阅读全文
0 0
原创粉丝点击