前提——我上交程序时再也不开O2了QWQ&&&数据千万条,清空第一条,数据不清空,最后泪两行(WA的一声哭了出来)
正文
看到这道题时,我就想到了51nod1515明辨是非。然而我刚写过1515的题解,我这到题还调了一个小时。{{{(>_<)}}}我还是太菜了,嘤嘤嘤
这道题要比明辨是非要简单,因为你不要对每一次操作进行询问,也不需要强制不等即不需要合并set。
思路大概是这样的:
他问的是每一组询问是否可以实现,所以可以先把相等的合并,在一条一条的看是否不相等的可以不相等。如果可以,就输出YES否则就输出NO
要注意,一定要先去维护相等的关系,再去查看,因为你的查看是不会影响到合并的,所以当你写的程序中遇见了下面这种排序方式:
- x1!=x2 查询,成立
- x1=x2 维护,则此时楼上不再成立,你应该输出NO,但事实上你会输出YES
你的程序运行有先后之分,但是实际的逻辑运算是不会这样的,所以应该先SORT一遍,把维护相等关系的先干了,再扫一边不相等的的查询,设置一个BOOL变量来看你之中是否之前已经不符合了。
记得离散化时不要用MAP,除非你想要成为一个T
愉悦的代码时间
同样的,代码中也有注释
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 //请养成好的阅读习惯:全局变量->主函数->根据主函数的调用看函数 7 inline int read(){ 8 int f=1,x=0; char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} 10 while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar(); 11 return f*x; 12 } 13 const int maxn=100005; 14 struct ziji{int x,y,e;}a[maxn]; //正常的数据存储&&离散化完成后的存储 15 bool cmp(ziji x,ziji y){return x.e>y.e;}//先维护,后查询 16 int t,n,f[maxn],b[maxn<<1];//f[]是正常并查集的father,b是你离散化要用的 17 //记住,b一定要开MAXN<<1的大小,因为你的操作是n的,但每次操作里有俩数 18 inline int find(int x){return x==f[x]?x:f[x]=find(f[x]);}//找爸爸 19 int main(){ 20 t=read(); 21 while (t--){ 22 //每组数据都有属于自己的烟火 23 memset(a,0,sizeof(a)); 24 memset(b,0,sizeof(b)); 25 memset(f,0,sizeof(f)); 26 //所以你一定要MEMSET啊!!!我因此多调了20分钟QAQ 27 //还有二十分钟是因为我开O2后我的代码T了,然后在我看了二十分钟后忍无可忍时 28 //我交了一份不开O2的代码。然后我A了,,,, 29 //F**K 30 n=read();int tot=0; 31 //tot是存储b中的数字个数的 32 for (register int i=1;i<=n;++i){ 33 a[i].x=read();a[i].y=read();a[i].e=read(); 34 b[++tot]=a[i].x;b[++tot]=a[i].y; 35 }//把x,y导入b[]中 36 sort(b+1,b+1+tot);//离散化开始。 37 ///先SORT再去重,离散化后的数就是b[]中的下标 38 int num=unique(b+1,b+1+tot)-b; 39 for(register int i=1;i<=n;++i){ 40 a[i].x=lower_bound(b+1,b+1+num,a[i].x)-b; 41 a[i].y=lower_bound(b+1,b+1+num,a[i].y)-b; 42 } 43 for(register int i=1;i<=num;++i) f[i]=i;//并查集的初始化 44 sort(a+1,a+1+n,cmp);//先1后0 45 bool flag=true;//判断你是否程序中有错 46 //下面就是并查集的正常操作了:维护就是并,查询就是看爸爸 47 for(register int i=1;i<=n;++i){ 48 if(a[i].e==1){ 49 int f1=find(a[i].x),f2=find(a[i].y); 50 if(f1!=f2) f[f1]=f2; 51 } 52 else{ 53 int f1=find(a[i].x),f2=find(a[i].y); 54 if(f1==f2){ 55 flag=false;break; 56 } 57 } 58 } 59 if (flag==true) printf("YES\n"); 60 else printf("NO\n"); 61 } 62 return 0;//功德圆满 63 }
国际惯例
希望可以有某位好心的大佬告诉我为什么我这份代码吸氧时会厌氧,在下感激不尽。
同样的,对我代码有不懂的地方欢迎提问
thankyou for your attention