合纵连横

xiaoxiao2021-02-28  93

题目:

合纵连横

时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 3 描述

乱世天下,诸侯割据。每个诸侯王都有一片自己的领土。但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大。而实力弱的诸侯王为了不让自己的领土被吞并,他会联合一些其他同样弱小的诸侯国,组成联盟(联盟不止一个),来共同抵抗那些强大的诸侯国。 强大的诸侯国为了瓦解这些联盟,派出了最优秀的间谍来离间他们,使一些诸侯国退出联盟。最开始,每个诸侯国是一个联盟。

有两种操作

1、U x y 表示xy在同一个联盟。0x,y<n

2、D x   表示x退出联盟。

输入 多组测试数据 第一行两个数,n和m(1 ≤ n≤ 10^5, 1 ≤ m ≤10^5),分别表示诸侯国的个数和操作次数。 接下来有m行操作 输出 Case #1: 2 Case #2: 9 输出联盟的个数 样例输入 5 7 U 0 1 U 1 2 U 0 3 D 0 U 1 4 D 2 U 0 2 10 1 U 0 9 样例输出 Case #1: 2 Case #2: 9

心得:

 :一开始我用数组元素增减来做,没有完成,然后看到大神之作,想法清晰易懂 考察 交并集删减算法 将诸侯国当成食物,用food[]储存所装入的箱子点编号。food[2]=2;表示编号为2的食物放入编号为2的箱子,box[2]=3表示编号为2的箱子的钩子钩上编号为3的箱子。 如果有诸侯国联盟,首先查看当前是否属于一个联盟,find()函数寻找箱子连接的根源。若根源相同,表示属于同一棵树(同一个集合);若不相同,将两者连接。 如果有诸侯国退出联盟,将箱子里的食物拿出来,放在另一个空箱子里,并将这个箱子的钩子勾住自己。在这个过程中,箱子依然在,不会影响节点。 超时问题: find()函数采用递归方法完成根源的寻找,一开始我是写return find(box[x]);结果   超时了,然后改成return box[x]=find(box[x]);解决了超时问题,原因在于前者个箱子之间以 链状(或数状) 相连,箱子的根源为树根,寻找根源可能要好多步;后者是为  散发式,中间一点为根源,寻找根源的时候只需要一步,减少了循环次数

代码<C语言>:

#include <stdio.h> #include <string.h> int box[1000050]; int food[1000050]; int mark[1000050];//用来标志根源箱子 int find(int x)//寻找箱子所连接时最初的根源(根源的箱子上面的钩子必会钩在自己身上) { if(x==box[x])//如果箱子就连接在自己身上 return x; return box[x]=find(box[x]);//递归运算,最终总会满足if条件 } void Com(int x,int y) { int fx,fy; fx=find(x); fy=find(y); if(fx!=fy)//如果两个箱子的根源不一样 box[fx]=fy;//将第一个箱子的根源箱子上的锁连接到第二个箱子的根源箱子 } int main() { char ch; int n,m,x,y,ans,t,i,count=1; while(scanf("%d%d",&n,&m)!=EOF) { t=n;//为下面要用到空箱子做准备 for(i=0;i<n;i++)//初始状态 {food[i]=i;//将食物i放入编号为i的box里 box[i]=i;//将编号为i的box上的钩钩自己 } for(i=0;i<m;i++) { getchar();//读取回车键 scanf("%c",&ch); if(ch=='U') { scanf("%d%d",&x,&y); Com(food[x],food[y]);//合并就是把箱子的挂钩钩上。 } else //如果退出联盟 { scanf("%d",&x); food[x]=t;//拿掉box里的food,并把食物放入另一个空箱子,即编号为t的box,前面t=n就是为这个做准备 box[t]=t;//并把这个box的挂钩钩自己 t++; } } ans=0; memset(mark,0,sizeof(mark));//将数组中的元素全部赋值为0 for(i=0;i<n;i++) { if(mark[find(food[i])]==0) {mark[find(food[i])]=1;//赋值为1后,再有箱子的有相同的根源,就不会等于0了,就不会增加ans(很妙!) ans++;} } printf("Case #%d: %d\n",count++,ans);//拥有同一个根源的箱子为一个联盟 } return 0; }

AC情况:

转载请注明原文地址: https://www.6miu.com/read-42925.html

最新回复(0)