NOI2015 程序自动分析
题意:
有一些变量$x_{i}$,给出$n$个形如"$i,j,e$"的约束条件,判断能否存在一个$x$的赋值方案满足所有约束.
$e=0$ 表示$x_{i}=x_{j}$
$e=1$ 表示$x_{i}≠x_{j}$
$n<=10^{5},i,j<=10^{9},e={0,1}$
题解:
先处理所有$e=0 $的约束,把相等的变量用并查集并起来.
对于$e=1$的约束,如果$i$和$j$在同一集合就无解.
其他情况都有解.
注意
1)下标范围可能很大,所以进行离散或者哈希处理.
2)记得给询问按照$e$排序啊啊啊!!!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<ctime> #include<cstdlib> #include<cmath> #include<string> #include<vector> #include<map> #include<queue> #include<bitset> #define ll long long #define debug(x) cout<<#x<<" "<<x<<endl; #define db(x,y)cout<<#x<<" "<<#y<<" "<<x<<" "<<y<<endl; using namespace std; inline void rd(int &res){ res=0;char c; while(c=getchar(),c<48); do res=(res<<1)+(res<<3)+(c^48); while(c=getchar(),c>=48); } inline void print(int x){ if(!x)return ; print(x/10); putchar((x%10)^48); } inline void sc(int x){ if(x<0){x=-x;putchar('-');} print(x); if(!x)putchar('0'); putchar('\n'); } inline void Max(int &x,int y){if(x<y)x=y;} inline void Min(int &x,int y){if(x>y)x=y;} const int M=2e5+5; int t=0,s[M],n,fa[M]; struct node{ int x,y,e; bool operator<(const node &tmp)const{ return e>tmp.e; } }q[M]; int get(int x){ if(fa[x]!=x)return fa[x]=get(fa[x]); return x; } int main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); int cas,x,y,i,a,b,c; rd(cas); while(cas--){ rd(n); int res=1,t=0; for(i=1;i<=n;i++){ rd(q[i].x),rd(q[i].y),rd(q[i].e); s[t++]=q[i].x,s[t++]=q[i].y; } sort(q+1,q+1+n); sort(s,s+t); t=unique(s,s+t)-s; for(i=1;i<=t;i++)fa[i]=i; for(i=1;i<=n;i++){ x=lower_bound(s,s+t,q[i].x)-s+1; y=lower_bound(s,s+t,q[i].y)-s+1; a=get(x),b=get(y); if(q[i].e&&a!=b)fa[a]=b; else if(!q[i].e&&a==b){ res=0;break; } } if(res)puts("YES"); else puts("NO"); } return 0; }
$By\ LIN452$
$2017.06.07$