BZOJ 4195 & UOJ 127 [Noi2015]程序自动分析

来源:互联网 发布:俄亥俄州立大学知乎 编辑:程序博客网 时间:2024/04/26 05:06

并查集

出现矛盾当且仅当x1=x2且x1!=x2

于是先对i,j进行离散(我用的是排序离散+二分查找)。对于所有等于条件,把两个数用并查集并起来,对于每一个不等于判断一下就好了

NOI为什么会有这种题。。。

#include<map>#include<cstdio>#include<cstring>#include<algorithm>#define N 100005using namespace std;int a[N], b[N], c[N], fa[2*N], arr[2*N], tot;int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}int get(int x){    int l=1, r=tot;    while(l<r)    {        int mid=(l+r)>>1;        if(arr[mid]==x)return mid;        else if(arr[mid]<x)l=mid+1;        else r=mid-1;    }    return l;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        tot=0;        int n;        bool flag=1;        scanf("%d",&n);        for(int i = 1; i <= n; i++)        {            scanf("%d%d%d",&a[i],&b[i],&c[i]);            arr[++tot]=a[i];            arr[++tot]=b[i];        }        sort(arr+1, arr+1+tot);        int j=1;        for(int i = 1; i <= tot; i++)            if(arr[i]!=arr[i-1])                arr[j++]=arr[i];        tot=j-1;        for(int i = 1; i <= tot; i++)fa[i]=i;        for(int i = 1; i <= n; i++)            if(c[i]==1)                fa[find(get(a[i]))]=find(get(b[i]));        for(int i = 1; i <= n; i++)            if(c[i]==0 && find(get(a[i]))==find(get(b[i])))            {                flag=0;                printf("NO\n");                break;            }        if(flag)printf("YES\n");    }}
0 0