<span>周更2(并查集)</span>

1.  POJ - 1308 Is It A Tree?

题意:给你一堆点队,问能否组成一棵树。

题解:如果两个点有相同的祖宗或对于这个图有不止一个根节点,则这不是一棵树,否则是一颗树。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 using namespace std;
 5 
 6 int par[1001000];
 7 
 8 int find(int x)
 9 {
10 
11     while(x!=par[x]) x=par[x];
12     return x;
13 
14 }
15 
16 void  unionn(int x,int y)
17 {
18     int fa=find(x);
19     int fb=find(y);
20     if(fa!=fb) par[fa]=fb;
21 }
22 
23 int main()
24 {
25     int n,m;
26     int t=1;
27     while(1){
28         int flag=0;
29         memset(par,0,sizeof (par));
30         while(scanf("%d%d",&n,&m)&&n&&m){
31             if(n==-1&&m==-1) return 0;
32             if(!par[n]) par[n]=n;if(!par[m]) par[m]=m;
33             if(find(n)==find(m)) flag=1;    //两点在同一个并查集内
34             if(!flag) unionn(n,m);
35         }
36         int ans=0;
37         for(int i=1;i<10010;i++)
38             if(par[i]==i) ans++;      //不止一颗树
39         if(flag||ans>1) printf("Case %d is not a tree.\n",t++);
40         else printf("Case %d is a tree.\n",t++);
41     }
42     return 0;
43 }
View Code

 

2. POJ - 2912 Rochambeau

题意:给出n个人石头剪刀布的结果,问哪个人是裁判,裁判可以随便瞎出,不影响比赛结果。

题解:暴力枚举裁判,判断当此人是裁判时,结果会不会出现矛盾,没有出现矛盾,此人就是裁判;出现矛盾则说明此人不是裁判。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 using namespace std;
 5 
 6 int par[10010];
 7 int d[10100];
 8 struct node
 9 {
10     int a,b;
11     char c;
12 }p[10010];
13 
14 int find(int x)
15 {
16     int t=par[x];
17     if(t!=x){
18         par[x]=find(par[x]);
19         d[x]=(d[x]+d[t])%3;
20     }
21     return par[x];
22 }
23 
24 int unionn(int x,int y,int z)
25 {
26     int fa=find(x);
27     int fb=find(y);
28     if(fa==fb) {
29         if((d[x]-d[y]+3)%3!=z) return 1;
30     }
31     else{
32         par[fa]=fb;
33         d[fa]=(d[y]-d[x]+z+3)%3;
34     }
35     return 0;
36 }
37 
38 int main()
39 {
40     int n,m;
41     while(scanf("%d%d",&n,&m)!=EOF){
42         int gg=0,k,flag=1,sum=0;
43         memset(p,0,sizeof p);
44         if(m==0) {printf("Player 0 can be determined to be the judge after 0 lines\n");continue;}
45         for(int i=1;i<=m;i++){
46             scanf("%d%c%d",&p[i].a,&p[i].c,&p[i].b);
47         }
48         for(int i=0;i<n;i++){
49             flag=1;
50             for(int j=0;j<n;j++)
51                 par[j]=j,d[j]=0;
52             for(int j=1;j<=m;j++){
53                 int z;
54                 if(p[j].a==i||p[j].b==i) continue;
55                 if(p[j].c=='=') z=0;
56                 else if(p[j].c=='<') z=2;
57                 else if(p[j].c=='>') z=1;
58                 if(unionn(p[j].a,p[j].b,z)){
59                     flag=0;
60                     gg=max(gg,j);
61                     break;
62                 }
63             }
64             if(flag){
65                 k=i;
66                 sum++;
67             }
68         }
69         if(sum>1) printf("Can not determine\n");
70         else if(!sum) printf("Impossible\n");
71         else printf("Player %d can be determined to be the judge after %d lines\n",k,gg);
72     }
73     return 0;
74 }
View Code

 

3.  POJ - 1984 Navigation Nightmare

题意:给出多对点和两点之间的位置关系,然后给出一系列询问,表示在第几个关系给出后询问某两点的曼哈顿距离,如果距离未知则输出-1。

题解:把位置坐标分为x轴和y轴,所以有两个权值,x[i]记录i的x轴到其根节点x轴的距离,y[i]记录i的y轴到其根节点y轴的距离,(压缩路径和合并集合时权值的改变类似于向量的加减),把询问离线存储再判断。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<math.h>
 5 using namespace std;
 6 
 7 int par[1010000];
 8 
 9 struct node
10 {
11     int u,v,w;
12     char f;
13 }p[1001000];
14 
15 int xx[100100],yy[100100];
16 
17 int find(int x)
18 {
19     int t=par[x];
20     if(x!=par[x]) {
21         par[x]=find(par[x]);
22         xx[x]+=xx[t];
23         yy[x]+=yy[t];
24     }
25     return par[x];
26 }
27 
28 void unionn(int num)
29 {
30     int u=p[num].u;
31     int v=p[num].v;
32     char f=p[num].f;
33     int fa=find(u);
34     int fb=find(v);
35     if(fa==fb) return ;
36     par[fa]=fb;
37     xx[fa]=xx[v]-xx[u];
38     yy[fa]=yy[v]-yy[u];
39     if(f=='N') yy[fa]-=p[num].w;
40     if(f=='W') xx[fa]+=p[num].w;
41     if(f=='S') yy[fa]+=p[num].w;
42     if(f=='E') xx[fa]-=p[num].w;
43 }
44 
45 int main()
46 {
47     int n,m;
48     scanf("%d%d",&n,&m);
49     for(int i=1;i<=n;i++){
50         par[i]=i;
51         xx[i]=0,yy[i]=0;
52     }
53     for(int i=0;i<m;i++){
54         scanf("%d%d%d %c",&p[i].u,&p[i].v,&p[i].w,&p[i].f);
55     }
56     int t;
57     scanf("%d",&t);
58     int st=0;
59     while(t--){
60         int x,y,z;
61         scanf("%d%d%d",&x,&y,&z);
62         for(int i=st;i<z;i++){
63             unionn(i);
64         }
65         st=z;
66         int fa=find(x);
67         int fb=find(y);
68         if(fa!=fb) printf("-1\n");
69         else printf("%d\n",abs(xx[x]-xx[y])+abs(yy[x]-yy[y]));
70     }
71     return 0;
72 }
View Code

 

4. POJ - 1456 Supermarket 

 题意:有N件商品,价格为p,保质期为d。只能在保质期之前卖出去,并且每天只能卖出一个。求最大的利润。

题解:先安排价格高的商品,最好是放在保质期d那一天,如果已经被占了就往前找(类似并查集找祖宗的过程)。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<queue>
 4 #include<iostream>
 5 #include<string.h>
 6 using namespace std;
 7 
 8 struct node
 9 {
10     int a,b;
11 }p[1001000];
12 
13 int vis[1000100];
14 
15 int cmp(node x,node y)
16 {
17     if(x.a==y.a) return x.b>y.b;
18     return x.a>y.a;
19 }
20 
21 int main()
22 {
23     int n;
24     while(scanf("%d",&n)!=EOF){
25         memset(vis,0,sizeof vis);
26         memset(p,0,sizeof p);
27         for(int i=0;i<n;i++){
28             scanf("%d%d",&p[i].a,&p[i].b);
29         }
30         sort(p,p+n,cmp);
31         int sum=0;
32         for(int i=0;i<n;i++){
33             int j=p[i].b;
34             while(vis[j]&&j>0) j--;
35             if(j==0) continue;
36             if(!vis[j]) sum+=p[i].a,vis[j]=1;
37         }
38         printf("%d\n",sum);
39     }
40     return 0;
41 }
View Code
全部评论

相关推荐

02-14 07:38
已编辑
门头沟学院 Java
2.4&nbsp;一面2.6&nbsp;二面2.9&nbsp;三面(hr面)2.13&nbsp;oc1.15号收到面试电话那会就开始准备,因为一开始没底所以选择推迟一段时间面试,之后开始准备八股,准备实习可能会问的东西,这期间hot100过了有六七遍,真的是做吐了快,八股也是背了忘,忘了背,面经也看了很多,虽然最后用上的只有几道题,可是谁知道会问什么呢自从大二上开始学java以来,一路走来真的太痛了,一开始做外卖,点评,学微服务,大二下五六月时,开始投简历,哎,投了一千份了无音讯,开始怀疑自己(虽然能力确实很一般),后来去到一家小小厂,但是并不能学到什么东西,而且很多东西都很不规范,没待多久便离开,大二暑假基本上摆烂很怀疑自己,大三上因为某些原因开始继续学,期间也受到一俩个中小厂的offer,不过学校不知道为啥又不允许中小厂实习只允许大厂加上待遇不太好所以也没去,感觉自己后端能力很一般,于是便打算转战测开,学习了一些比较简单的测试理论(没有很深入的学),然后十二月又开始继续投,java和测开都投,不过好像并没有几个面试,有点打击不过并没有放弃心里还是想争一口气,一月初因为学校事比较多加上考试便有几天没有继续投,10号放假后便继续,想着放假应该很多人辞职可能机会大一点,直到接到字节的面试,心里挺激动的,总算有大厂面试了,虽然很开心,但同时压力也很大,心里真的很想很想很想进,一面前几天晚上都睡不好觉,基本上都是二三点睡六七点醒了,好在幸运终于眷顾我一次了(可能是之前太痛了),一面三十几分钟结束,问的都不太难,而且面试官人挺好但是有些问题问的很刁钻问到了测试的一些思想并不是理论,我不太了解这方面,但是也会给我讲一讲他的理解,但是面完很伤心觉得自己要挂了。但是幸运的是一面过了(感谢面试官),两天后二面,问的同样不算难,手撕也比较简单,但也有一两个没答出来,面试官人很好并没有追问,因为是周五进行的二面,没有立即出结果,等到周一才通知到过了,很煎熬的两天,根本睡不好,好在下周一终于通知二面过了(感谢面试官),然后约第二天三面,听别的字节同学说hr面基本上是谈薪资了,但是我的并不是,hr还问了业务相关的问题,不过问的比较浅,hr还问我好像比较紧张,而且hr明确说了还要比较一下,我说我有几家的面试都拒了就在等字节的面试(当然紧张,紧张到爆了要),三面完后就开始等结果,这几天干啥都没什么劲,等的好煎熬,终于13号下午接到了电话通知oc了,正式邮件也同时发了,接到以后真的不敢信,很激动但更重要的是可以松一口气了,可以安心的休息一下了终于可以带着个好消息过年了,找实习也可以稍微告一段落了,虽然本人很菜,但是感谢字节收留,成为忠诚的节孝子了因为问的比较简单,面经就挑几个记得的写一下一面:1.实习项目的难点说一下2.针对抖音评论设计一下测试用例3.手撕:合并两个有序数组二面:1.为什么转测开2.线程进程区别,什么场景适合用哪个3.发送一个朋友圈,从发出到别人看到,从数据流转的角度说一下会经历哪些过程4.针对抖音刷到广告视频设计测试用例5.手撕:无重复字符的最长字串
查看8道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务