首页 > 代码库 > hdu1856 选出更多的孩子
hdu1856 选出更多的孩子
题目大意:
老师选取2个学生对应的号码,这两人视作朋友,同时朋友的朋友也可以看成自己的朋友。
最后老师选出一个人数最多的朋友圈。
这里学生的人数不大于10^7,所以操作时需要极为注意,操作步数能省则省。
我也在超时了两次之后,不断进行代码优化才做出。
超时的部分函数代码:
1 int getHead(int x)2 {3 while(x!=fa[x]) x=fa[x];4 return x;5 }
后来在这个代码基础上加了int a=x;return前加一个fa[a]=x;这样在查找顶点时,同时将路径进行压缩,下次再去查找时就不会有重复的操作。
之前的联合函数
void Union(int x,int y)
{
int fa_x=getHead(x);
int fa_y=getHead(y);
if(fa_x!=fa_y) {fa[fa_x]=fa_y;K[fa_y]+=K[fa_x];}
}
这是将每个作为顶点位置上对应的小组人数保存在K数组中,但是这样在main函数中要对K数组进行一次遍历(10^7次的操作,又浪费时间了)
所以后来引进了Max的全局变量,每次结合时就更新Max,那么main函数中直接输出Max即可.
改过之后函数变为:
void Union(int x,int y)
{
int fa_x=getHead(x);
int fa_y=getHead(y);
if(fa_x!=fa_y) {fa[fa_x]=fa_y,fa[x]=fa_y;K[fa_y]+=K[fa_x];}
Max=max(Max,K[fa_y]);
}
总体代码如下:
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define MAXN 10000100 6 int Max; 7 int fa[MAXN],K[MAXN]; 8 9 int max(int x,int y)10 {11 return x>y?x:y;12 }13 int getHead(int x)14 {15 int a=x;16 while(x!=fa[x]) x=fa[x];17 fa[a]=x;18 return x;19 }20 void Union(int x,int y)21 {22 int fa_x=getHead(x);23 int fa_y=getHead(y);24 if(fa_x!=fa_y) {fa[fa_x]=fa_y,fa[x]=fa_y;K[fa_y]+=K[fa_x];}25 Max=max(Max,K[fa_y]);26 }27 int main()28 {29 int n,t;30 while(scanf("%d",&n)!=EOF){31 t=0;32 int *a=new int[n];33 int *b=new int[n];34 for(int i=1;i<=MAXN;i++){35 K[i]=1;36 fa[i]=i;37 }38 Max=1;39 for(int i=0;i<n;i++){40 scanf("%d%d",&a[i],&b[i]);41 Union(a[i],b[i]);42 }43 44 printf("%d\n",Max);45 }46 return 0;47 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。