[NOI2015] BZOJ4195 程序自动分析-离散化-并查集

来源:互联网 发布:淘宝发展史宣传片 编辑:程序博客网 时间:2024/05/17 09:20

传送门:右转进入题目

题目大意:给定n个式子形如xi=xj或者xi!=xj。问是否可能?

首先这个题数据范围大,先离散化一下。

然后发现输入顺序不影响答案,所以先考虑等号,就是并查集维护一下即可。

对于不等号,如果find出来是在同一个集合里就是NO并退出。

最后输出YES。

水题……QwQ

//NOI  2015//BZOJ 4195#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define MAXN 2000010using namespace std;int fa[MAXN],qu[MAXN],qv[MAXN],qopt[MAXN];vector<int> v;inline int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}inline int findf(int x){int fx=x,y;while(fx!=fa[fx]) fx=fa[fx];while(x!=fx) y=fa[x],fa[x]=fx,x=y;return fx;}inline int merge_union(int x,int y){fa[x]=y;return 0;}int main(){int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d%d",&qu[i],&qv[i],&qopt[i]);v.push_back(qu[i]);v.push_back(qv[i]);}sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());for(int i=1;i<=n;i++)qu[i]=getid(qu[i]),qv[i]=getid(qv[i]);for(int i=1;i<=v.size();i++) fa[i]=i;for(int i=1;i<=n;i++)if(qopt[i]){int fu=findf(qu[i]),fv=findf(qv[i]);if(fu!=fv) merge_union(fu,fv);}bool f=false;for(int i=1;i<=n;i++)if(!qopt[i]){int fu=findf(qu[i]),fv=findf(qv[i]);if(fu==fv){printf("NO\n");f=true;break;}}if(f) continue;printf("YES\n");}return 0;}


0 0
原创粉丝点击