【bzoj4195】【NOI2015】程序自动分析
4195: [Noi2015]程序自动分析
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3470 Solved: 1626
[Submit][Status][Discuss]
Description
在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。
考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x1≠x4,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
现在给出一些约束满足问题,请分别对它们进行判定。
Input
输入文件的第1行包含1个正整数t,表示需要判定的问题个数。注意这些问题之间是相互独立的。
对于每个问题,包含若干行:
第1行包含1个正整数n,表示该问题中需要被满足的约束条件个数。
接下来n行,每行包括3个整数i,j,e,描述1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若e=1,则该约束条件为xi=xj;若e=0,则该约束条件为xi≠xj。
1≤n≤1000000
1≤i,j≤1000000000
题解:
这题可以离线,并且是对整体进行询问,直接离线所有判断,然后并查集合并所有等号,对不等号一一判断即可;
想说的是这个题的在线版本(ORZ wwwwodddd)
依旧用并查集,但是用set对每个并查集维护一个敌人集合,然后合并两个集合的时候启发式合并set即可,需要离散化;(两份代码都放了OVO)
复杂度O(nlogn)
1 2 #include<bits/stdc++.h> 3 using namespace std; 4 const int N=2000010; 5 int T,n,tot,tx[N],ty[N],cnt,fa[N]; 6 map<int,int>mp; 7 int get(int x){ 8 if(!mp[x])mp[x]=++tot,fa[tot]=tot; 9 return mp[x]; 10 } 11 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 12 int main(){ 13 // freopen("bzoj4195.in","r",stdin); 14 // freopen("bzoj4195.out","w",stdout); 15 scanf("%d",&T); 16 while(T--){ 17 scanf("%d",&n); 18 tot=cnt=0;mp.clear(); 19 for(int i=1,x,y,e;i<=n;i++){ 20 scanf("%d%d%d",&x,&y,&e); 21 x=get(x);y=get(y); 22 if(e){ 23 int fx=find(x),fy=find(y); 24 if(fx!=fy)fa[fx]=fy; 25 }else tx[++cnt]=x,ty[cnt]=y; 26 } 27 int fg=0; 28 for(int i=1;i<=cnt;i++)if(find(tx[i])==find(ty[i])){fg=1;break;} 29 puts(fg?"NO":"YES"); 30 } 31 return 0; 32 }
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cmath> 7 #include<vector> 8 #include<stack> 9 #include<map> 10 #include<set> 11 #define Run(i,l,r) for(int i=l;i<=r;i++) 12 #define Don(i,l,r) for(int i=l;i>=r;i--) 13 #define ll long long 14 #define inf 0x3f3f3f3f 15 using namespace std; 16 const int N=200010; 17 int n,m,sub[N],tot,fa[N]; 18 struct data{ 19 int x,y,p; 20 data(int _x=0,int _y=0,int _p=0):x(_x),y(_y),p(_p){}; 21 }A[N]; 22 set<int>s[N]; 23 set<int>::iterator it; 24 char gc(){ 25 static char*p1,*p2,S[1000000]; 26 if(p1==p2)p2=(p1=S)+fread(S,1,1000000,stdin); 27 return(p1==p2)?EOF:*p1++; 28 } 29 int rd(){ 30 int x=0,f=1; char c=gc(); 31 while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();} 32 while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc(); 33 return x*f; 34 } 35 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 36 bool check(int x,int y){ 37 if(x==y)return false; 38 if(s[x].size()>s[y].size())swap(x,y); 39 for(it=s[x].begin();it!=s[x].end();it++){ 40 if(find(*it)==y)return true; 41 } 42 fa[x]=y; 43 for(it=s[x].begin();it!=s[x].end();it++){ 44 s[y].insert(find(*it)); 45 } 46 s[x].clear(); 47 return false; 48 } 49 int main(){ 50 // freopen("mzoj1292.in","r",stdin); 51 // freopen("mzoj1292.out","w",stdout); 52 //scanf("%d",&n); 53 n=rd(); 54 Run(i,1,n){ 55 //A[i]=(data){rd(),rd(),rd()}; 56 //scanf("%d%d%d",&A[i].x,&A[i].y,&A[i].p); 57 A[i].x=rd(); A[i].y=rd(); A[i].p=rd(); 58 sub[++tot]=A[i].x , sub[++tot]=A[i].y; 59 } 60 sort(sub+1,sub+tot+1); 61 tot=unique(sub+1,sub+tot+1)-sub-1; 62 Run(i,1,tot)fa[i]=i; 63 for(int i=1,x,y;i<=n;i++){ 64 x=A[i].x=lower_bound(sub+1,sub+tot+1,A[i].x)-sub; 65 y=A[i].y=lower_bound(sub+1,sub+tot+1,A[i].y)-sub; 66 if(A[i].p==0){ 67 if(find(x)==find(y)){puts("No");continue;} 68 puts("Yes"); 69 s[fa[x]].insert(fa[y]); 70 s[fa[y]].insert(fa[x]); 71 }else { 72 int fx=find(x) , fy=find(y); 73 if(check(fx,fy)){puts("No");continue;} 74 else puts("Yes"); 75 } 76 } 77 return 0; 78 }//by tkys_Austin;