程序自动分析——题解

前提——我上交程序时再也不开O2了QWQ&&&数据千万条,清空第一条,数据不清空,最后泪两行(WA的一声哭了出来)

正文

传送门-->洛谷ORbzoj

看到这道题时,我就想到了51nod1515明辨是非。然而我刚写过1515的题解,我这到题还调了一个小时。{{{(>_<)}}}我还是太菜了,嘤嘤嘤

这道题要比明辨是非要简单,因为你不要对每一次操作进行询问,也不需要强制不等即不需要合并set。

思路大概是这样的:

他问的是每一组询问是否可以实现,所以可以先把相等的合并,在一条一条的看是否不相等的可以不相等。如果可以,就输出YES否则就输出NO

注意,一定要先去维护相等的关系,再去查看,因为你的查看是不会影响到合并的,所以当你写的程序中遇见了下面这种排序方式:

  1. x1!=x2  查询,成立
  2. 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 }
View Code

国际惯例

希望可以有某位好心的大佬告诉我为什么我这份代码吸氧时会厌氧,在下感激不尽。

同样的,对我代码有不懂的地方欢迎提问

thankyou for your attention

 
 
 
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/fallen-down/p/10714018.html