UVA 10608 Friends 并查集

4 篇文章 0 订阅
2 篇文章 0 订阅

题目链接:http://vjudge.net/problem/viewProblem.action?id=20432

题目大意:朋友的朋友是朋友,求人数最多的那帮家伙有多少人。

         我刚开始真尝试了一遍的一步一步用数组模拟搜索,拼接······,果断超时了,下次不干那么无聊的事了,明明有好算法,干嘛还暴力呢?

这是基本的并查集的题目,参考代码如下:      

#include <stdio.h>
int fa[30001],tot[30001];
int find(int u)
{
    fa[u]==u?u:fa[u]=find(fa[u]);
    return fa[u];

}
int main()
{
    int t,n,m,i,x,y,u,v,maxx;
      scanf("%d",&t);
        while (t--)
          {
              scanf("%d%d",&n,&m);
                for (i=1;i<=n;i++) {fa[i]=i,tot[i]=0;}
                  for (i=1;i<=m;i++)
                  {
                      scanf("%d%d",&u,&v);
                        x=find(u);y=find(v);
                      if (x!=y) fa[x]=y;
                  }
                  for (i=1;i<=n;i++) tot[find(i)]++;
                maxx=tot[1];
              for (i=2;i<=n;i++) if (tot[i]>maxx) maxx=tot[i];
            printf("%d\n",maxx);
          }
    return 0;
}

以下是我的暴力求解,仅供参考

每输入一次,分别在每一组中搜索有没有与其相等的数,如果只有一个数在其中一组已存在,那么把另一个数添加到这组;

如果两个数在不同的两组搜索到,那么就把两组连接上;如果两个数在同一组出现,不用操作。

#include<stdio.h>
#include <string.h>
int f[12000][30000],h[12000];
int main()
{
    int t,n,m,a,b,num=0,k,i,j;
    scanf("%d",&t);
      while (t--)
      {
          num=0;
          scanf("%d%d",&n,&m);
          scanf("%d%d",&a,&b);
          memset(h,0,sizeof(h));
            f[0][h[0]++]=a;f[0][h[0]++]=b;num++;m--;
              while(m--)
               {
                  scanf("%d%d",&a,&b);
                    int x[2],y=0;
                     for (i=0;i<num;i++)
                     {
                         k=0;
                         int s=h[i];
                         for (j=0;j<s;j++)
                           {
                               if (a==f[i][j]) {k++;f[i][h[i]++]=b;}
                                if (b==f[i][j]) {k++;f[i][h[i]++]=a;}
                                  if (k==2) break;
                           }
                          if (k==2)
                           {
                              h[i]-=2;
                              y=3;
                              break;
                           }
                           else if (k==1) x[y++]=i;
                           if (y==2)break;
                     }
                  if (y==0)
                  {
                      f[num][h[num]++]=a;
                        f[num][h[num]++]=b;
                          num++;
                  }
                  else if (y==2)
                  {
                    h[x[0]]--;
                      for(i=0;i<h[x[1]]-1;i++)
                        f[x[0]][h[x[0]]++]=f[x[1]][i];
                      memset(f[x[1]],0,sizeof(f[x[1]]));
                  }
               }
         int max1=h[0];
            for (i=0;i<num;i++);
              if (h[i]>max1) max1=h[i];
                 printf("%d\n",max1);
      }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值