这题没有用到2SAT的算法,不过用到了思想。挺好的,入门吧。
因为现在就是判断某两个人是不是在同一集合里,而2SAT正好就是解法这种问题的最好解法算法,其思想就是2个为布尔值的量一个真则另一个必假,一个假另一个必真。
所以设当前人为 i,则 i *2这个结点为真,那么根据2SAT,则 2*i+1为假。所以如果输入的a与b,如果!(a*2+1)&&b=true 或者 a&&!(b*2+1)=true则在不同的集合;如果a&&!(a*2+1)=true 或者 b&&!(b*2+1)=true,则为在同一集合里;否则为未确定。
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define sc(a,b) scanf("%d%d",&a,&b) #define pri(a) printf("%d\n",a) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define MM 1000005 #define MN 200010 #define INF 55566677 #define eps 1e-7 using namespace std; typedef long long ll; int f[MN]; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } int main() { int t,n,m; sca(t); while(t--) { sc(n,m); for(int i=1;i<=2*n+10;i++) f[i]=i; while(m--) { char s[3]; int x,y; scanf("%s%d%d",s,&x,&y); int x1=find(x*2); int y1=find(y*2); int x2=find(x*2+1); int y2=find(y*2+1); if(s[0]=='A') { if(x1==y2||x2==y1) puts("In different gangs."); else if(x1==y1||x2==y2) puts("In the same gang."); else puts("Not sure yet."); } else f[x1]=y2,f[x2]=y1; } } return 0; }