Fork me on GitHub

HDU1272-小希的迷宫

快结束了放一个数一巨巨acm路线

继续刷邝斌飞并查集专题

HDU1272

洛谷

这题不是带权并查集貌似,不管了,切他!

判断环? 出去扒拉几口盖浇饭回来就有思路了,不就是一个数有不同的pre前驱父亲,且这俩父亲指向了同一个终极根,诶不对,洛谷评分为啥为提高,这是HDU编程大赛AC人数第7的总共8个题,而且最主要的是这个多个父亲咋处理啊?

 

发现根据给定的数据画成有向树唯一前驱的形式,答案就是两个数的根是个相同的数且不是他们自己,不对不对,而且我发现画成有向树唯一前驱的形式第三个样例是8指向4指向2指向6指向8成环,但实际这几个数画成样例那种形式又是没问题的,好奇妙的玩意啊,问了下文心GPT样例这玩意叫图数据结构不叫树,树是每个节点最多只能有一个父节点(除了根节点没有父节点)和任意数量的子节点。

 

这题意可以想到的已学的思路几乎没有啊,没啥思路果断看题解

看到题解里这句话,在同一个集合就输出NO这也太简单了,提高难度?发现之前想对了,一时判断错就误以为是错的,就是两个数的根是一样的就是No

先写下吧,第一次WA了,发现要求有且仅有,即只有一个集合,反例:3 4 5 6 0 0,3和5就没路 

改完又WA,md自身到自身4 4 0 0也应该No,艹,对拍发现的。

对拍代码

 1 #include <iostream>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 #include<stdio.h>
 5 #include<iostream>
 6 #include<time.h>
 7 #include <string>
 8 #include <random>
 9 using namespace std;
10 int a,b;
11 int main(){
12     srand(time(0) + (unsigned long long)(new char));
13     for(int i=1;i<=7;i++){
14         int n = rand()%5+1;
15         int d = rand()%5+1;
16     cout<<n<<" "<<d<<endl;
17     }
18     cout<<"0 0"<<endl;
19     cout<<"-1 -1"<<endl;
20 
21 }
View Code

但改完依旧WA,看了眼vjudge的“Origin”那列,大佬提醒,0 0 相当于空图,应该Yes

改完直接AC

AC代码 —— 垃圾HDU连个discuss都没有艹,但杭电的acm确实牛逼,acm届扛把子

 1 //根据题意这题不会有自身指向自身和重复的情况吧,得了有也没事,照样判断
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #define MAX 100001
 6 using namespace std;
 7 int pre[MAX];
 8 int num;
 9 int find(int x)
10 {
11     if(x==pre[x])
12         return x;
13     pre[x]=find(pre[x]);
14     return pre[x];
15 }
16 //int union[MAX];//union是个关键字
17 int union_n[MAX];//确保有即能连通。初始全为0,当union_n数组里只有一个值为1的时候,即所有点都连在他上,那就证明了有,也就是只有一个集合,如果flag也为0,那就证明了仅有一条路。有且仅有。如果不止一个union_n值为1,证明啥,证明有多个集合,互不相通则肯定有集合1中的点到不了集合2中,则No
18 int flag;//确保不多即仅有一个。初始是0,任意两点之间如果多于一条路,就弄成1,flag是1则No
19 int main()
20 {
21     flag=0;
22     num=0;
23     memset(union_n,0,sizeof(union_n));
24     int a,b;
25     for(int i=1;i<MAX;i++){//很奇怪的事,不小心写成<=,然后num也随之被赋值成MAX了
26         pre[i]=i;
27 //    cout<<" "<<i<<" "<<pre[i]<<" "<<num<<endl;
28     }
29 //    cout<<" "<<num<<endl;
30     while(cin>>a>>b){
31         if(a==-1&&b==-1)
32             break;
33         if(a==0&&b==0){
34 
35             if((num==1||num==0) && flag==0)
36                 cout<<"Yes"<<endl;
37             else
38                 cout<<"No"<<endl;
39             for(int i=1;i<MAX;i++)
40                 pre[i]=i;
41             flag=0;
42             num=0;
43             memset(union_n,0,sizeof(union_n));
44             continue;
45         }
46         int root1=find(a);
47         int root2=find(b);
48 //        if((root1==root2) && (a!=b))//a!=b保证了自身指向自身别tm给我算成多于一条路
49         if((root1==root2) )//md自身到自身也不行,对拍发现的
50             flag=1;//证明ab之间有不止一条路了,输出No
51         else{
52             pre[root1]=root2;
53             if(union_n[root1]==1){
54                 num--;
55                 union_n[root1]=0;
56             }
57             if(union_n[root2]==0){
58                 num++;
59 //            cout<<"@"<<num<<endl;
60                 union_n[root2]=1;
61             }
62         }
63     }
64 }

洛谷AC代码 —— 洛谷是0/1,HDU是No/Yes

 1 //根据题意这题不会有自身指向自身和重复的情况吧,得了有也没事,照样判断
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #define MAX 100001
 6 using namespace std;
 7 int pre[MAX];
 8 int num;
 9 int find(int x)
10 {
11     if(x==pre[x])
12         return x;
13     pre[x]=find(pre[x]);
14     return pre[x];
15 }
16 //int union[MAX];//union是个关键字
17 int union_n[MAX];//确保有即能连通。初始全为0,当union_n数组里只有一个值为1的时候,即所有点都连在他上,那就证明了有,也就是只有一个集合,如果flag也为0,那就证明了仅有一条路。有且仅有。如果不止一个union_n值为1,证明啥,证明有多个集合,互不相通则肯定有集合1中的点到不了集合2中,则No
18 int flag;//确保不多即仅有一个。初始是0,任意两点之间如果多于一条路,就弄成1,flag是1则No
19 int main()
20 {
21     flag=0;
22     num=0;
23     memset(union_n,0,sizeof(union_n));
24     int a,b;
25     for(int i=1;i<MAX;i++){//很奇怪的事,不小心写成<=,然后num也随之被赋值成MAX了
26         pre[i]=i;
27 //    cout<<" "<<i<<" "<<pre[i]<<" "<<num<<endl;
28     }
29 //    cout<<" "<<num<<endl;
30     while(cin>>a>>b){
31         if(a==-1&&b==-1)
32             break;
33         if(a==0&&b==0){
34 
35             if((num==1||num==0) && flag==0)
36                 cout<<"1"<<endl;
37             else
38                 cout<<"0"<<endl;
39             for(int i=1;i<MAX;i++)
40                 pre[i]=i;
41             flag=0;
42             num=0;
43             memset(union_n,0,sizeof(union_n));
44             continue;
45         }
46         int root1=find(a);
47         int root2=find(b);
48 //        if((root1==root2) && (a!=b))//a!=b保证了自身指向自身别tm给我算成多于一条路
49         if((root1==root2) )//md自身到自身也不行,对拍发现的
50             flag=1;//证明ab之间有不止一条路了,输出No
51         else{
52             pre[root1]=root2;
53             if(union_n[root1]==1){
54                 num--;
55                 union_n[root1]=0;
56             }
57             if(union_n[root2]==0){
58                 num++;
59 //            cout<<"@"<<num<<endl;
60                 union_n[root2]=1;
61             }
62         }
63     }
64 }
View Code

 

总结:

0、注意有且仅有,即除了要判断,是否给的俩数有同根(说明这组数据使得出现了多条路),还要判断是否有,题目“任意两点之间都要有路”,即集合必须为1

1、自身到自身也算不符合,应该No

2、0 0属于空图,应该Yes,不应该直接结束去判断下一组(但在洛谷没有这个,0 0输出啥都可以AC)

洛谷的食物链评分是提高,How Many Answers Are Wrong洛谷没有但我认为(所有带权并查集都)应该是提高+,这题洛谷也是提高

 

看看洛谷其他做法,有克鲁斯卡尔最小生成树的做法(搁置,接下来刷最小生成树专题)

又看到了个惊为天人 东西,居然用搜索做,我是一点都看不懂,好奇查了下他用的fst数据吓到我了居然是什么有限状态机,就是first和next的简写而已,大概知道了,这大佬用了个近乎自己创造的一个存图方法来搜的,其中这句“对于搜到的每一个点,遍历与其相邻的每一个点,如果该点不是当前点的父节点且已经被搜过,则这个图不是树”保证了仅有一个,“搜索后看一看是不是所有点都被搜到了”这句话保证了有。不学这种,太tm高深了仿佛天山折梅手,貌似也没啥用其他写法可以平替,学起来还费劲,纯纯大炮打蚊子。

思考:搜索专题的oil那个题,判断连通块,这个也是连通块,但由于搜索都是给你地图,有坐标,x和y加一减一就可以找到下一个点,但现在是图,没有坐标,上面这大佬的做法是自己发明了个写法,来存点的序列,顺序往下存,开个数组指向存储的数组下标,貌似是手写map?不看这个了

 

简单看下剩下题的百度搜索结果:

到了现在这个AC人数排序的并查集刷题量,基本不会出现本身不会看一眼搜索结果就会的题,所以不用怕看了就影响心境干扰思路,可以稍微放心大胆的搜,做个整理

AC人数:类型

51:POJ1417结合了DP(DP先搁置

59:POJ1984带权并查集

64:POJ2912带权并查集

78:ZOJ3261逆向并查集

112:POJ1733离散化带权并查集

149:POJ1456结合了贪心DP(DP先搁置

197:POJ2492种类并查集

207:POJ1308并查集延伸

惊了,继洛谷和鸡肋POJ-discuss后,无意间发现有个超级给力的,邝斌飞vjudge专题里“Origin”那一列也是个不错的讨论区

打算最快速度把并查集搞完,主要是想多练习几个带权并查集!!!不然到食物链那个题就结束了

 

###:发现刷题的思路跟做题不一样,回忆判断是否有环的时候,无意间百度到这题我直接懵逼

###:为啥回忆最短路算法我脑袋空空啥也想不起来,百度查说SPFA是判断负环也做过正环的复杂度是O(VE),那一个点一个边,10^5个点,10^10直接爆炸,不可以最短路算法,再次证明用最短路就大材小用了徒增耗时。但并查集复杂度依旧先搁置

###:啊我思路好僵硬啊,刷并查集的时候一点都不想写刷过的其他算法搜索、最短路

###;哎这博客园的远古编辑器~~~~(>_<)~~~~

posted @ 2024-11-21 20:40  GerJCS  阅读(4)  评论(0编辑  收藏  举报