并查集 找k颗树使节点数最多

#include<algorithm>
#include <iostream>
#include <cstdio>
#include <string.h>

using namespace std;

int f[10002],num[10002];
int find(int x)
{
    return f[x]==x?x:f[x]=find(f[x]);
}

int main()
{
    int i,j,n,m,t,k,a,len,b;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(i=0;i<n;i++)
        {
            f[i]=i;
            num[i]=1;
        }
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            int aa=find(a);
            int bb=find(b);
            if(aa!=bb)
            {
                f[aa]=bb;
                num[bb]+=num[aa];
                num[aa]=0;
            }
        }
        for(i=0;i<n;i++)
            find(i);
        //for(i=0;i<n;i++)
        //    printf("__%d  ",num[i]);
        int ans=0,numi,final=0;

       sort(num,num+n);
       for(i=1;i<=k;i++)
           final+=num[n-i];
               printf("%d\n",final);
            
       
    }
    return 0;
}


       

小希的迷宫 :点是不连续的 注意每次要把f[i]=i 初始化 到 100002 

#include<iostream>
#include<stdio.h>
#include<string.h>

using namespace std;

struct node{int x;int y;} no[100002];

int f[200002],vis[200002];

int find(int x)
{
   return f[x]==x?x:f[x]=find(f[x]); 
}

int main()
{
    int i,a,b,aa,bb,maxx=0,num=0;
    memset(vis,0,sizeof(vis));
    while(~scanf("%d %d",&a,&b))
    {
    
        if(a==-1&&b==-1)
            break;
        else if(a==0&&b==0)
        {
            if(num==0)
            {
                printf("Yes\n");
                continue;
            }
            memset(f,0,sizeof(f));
            int flag=0;
            for(i=0;i<=100002;i++)
                f[i]=i;
            for(i=0;i<num;i++)
            {
                aa=find(no[i].x);
                bb=find(no[i].y);
                if(aa==bb)
                {
                    flag=1;
                    break;
                }
                else 
                    f[aa]=bb;
            }
            int cnt=0;
            for(i=0;i<=maxx;i++)
                if(vis[i]&&find(i)==i)
                    cnt++;


            if(!flag&&cnt==1)
                printf("Yes\n");
            else 
                printf("No\n");
                
            maxx=0;
            num=0;
            memset(vis,0,sizeof(vis));
        }
        else
        {
            vis[a]=vis[b]=1;
            no[num].x=a;
            no[num++].y=b;
            if(maxx<a)
                maxx=a;
            if(maxx<b)
                maxx=b;
        }
    }
    return 0;
}
View Code

 

posted @ 2013-10-07 16:11  galaxy77  阅读(163)  评论(0编辑  收藏  举报