hdu1213

简单模板

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<map>
using namespace std;
//hdu 1213
int node[1000+10];

int Find(int x)
{
    if(node[x] == x)
        return x;
    //压缩
    int root = Find(node[x]);
    node[x] = root;
    return root;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
            node[i] = i;
        for(int i=0;i<m;++i)
        {
            int a,b,x,y;
            scanf("%d%d",&a,&b);
            x = Find(a);
            y = Find(b);
            if(x != y)
            {
                node[x] = y;
            }
        }
        map<int,int> mii;
        int cnt = 0;
        for(int i=1;i<=n;++i)
        {
            int root = Find(i);
            pair<map<int,int>::iterator,bool> pmb = mii.insert(pair<int,int>(root,0));
            if(pmb.second)  ++cnt;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

/*
100
3 2
1 2
2 1
*/
View Code

hdu1232

简单模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

int node[1000+10];

int Find(int x)
{
    if(node[x] == x)
        return x;
    int root = Find(node[x]);
    node[x] = root;
    return root;
}

int main()
{
    int n,m;
    while(~scanf("%d",&n),n)
    {
        scanf("%d",&m);
        for(int i=1;i<=n;++i)
            node[i] = i;
        for(int i=0;i<m;++i)
        {
            int a,b,x,y;
            scanf("%d%d",&a,&b);
            x = Find(a);
            y = Find(b);
            if(x != y)
                node[x] = y;
        }
        int cnt = 0;
        for(int i=1;i<=n;++i)
            if(node[i] == i)
                ++cnt;
        printf("%d\n",cnt-1);
    }
    return 0;
}
View Code

 

hdu1272

判断是否有环。该题只输入0 0,要求输出Yes

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int node[100000+10];
int vis[100000+10];
int flag = 0;       //是否有环

int Find(int x)
{
    if(node[x] == x) return x;
    int y = Find(node[x]);
    node[x] = y;
    return y;
}

void Union(int a,int b)
{
    if(a == b) return;
    int x = Find(a);
    int y = Find(b);
    if(x == y) flag = 1;
    else{node[x] = y;}
}

int main()
{
    int a,b;
    while(true)
    {
        for(int i=0;i<=100000+10;++i)
            node[i] = i;
        memset(vis,0,sizeof(vis));
        flag = 0;
        while(~scanf("%d%d",&a,&b))
        {
            if(a==0 && b==0)  break;
            if(a==-1 && b==-1) break;
            if(!vis[a]){vis[a]=1;}
            if(!vis[b]){vis[b]=1;}
            Union(a,b);
        }
        if(a==-1 && b==-1) break;
        int p = 0;
        //确保只有一个连通图,p==1
        for(int i=1;i<100000+10;++i)
            if(vis[i]&&i == Find(i)) ++p;
        if(!flag && p<=1)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
View Code

 

hdu1325

跟1272类似,但是退出条件为小于0,小于0.并且在原有无环的判断条件后,增加了根的入度为0,节点的入度为1,才能会树。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N (10000+10)

int node[N];
int vis[N];
int indegree[N];
int tp;
int flag;

int Find(int x)
{
    if(node[x] == x) return x;
    int y = Find(node[x]);
    node[x] = y;
    return y;
}

void Union(int a,int b)
{
    if(a==b){flag = 1;return;}
    int x = Find(a);
    int y = Find(b);
    if(x==y) flag = 1;
    else node[x] = y;
}

int main()
{
    int t=0;
    while(true)
    {
        int a,b;
        for(int i=0;i<N;++i)
            node[i] = i;
        memset(vis,0,sizeof(vis));
        memset(indegree,0,sizeof(indegree));
        tp = 0;
        flag = 0;
        while(~scanf("%d%d",&a,&b))
        {
            if(a==0&&b==0) break;
            if(a<0&&b<0) break;
            vis[a] = 1;
            vis[b] = 1;
            ++indegree[b];
            Union(b,a);
        }
        if(a<0&&b<0) break;
        for(int i=0;i<N;++i)
        {
            if(!vis[i]) continue;
            if(i == Find(i)) ++tp;
            if(i == Find(i) && indegree[i]!=0) flag = 1;
            if(i != Find(i) && indegree[i]!=1) flag = 1;
            //if(i == Find(i)) printf("test %d\n",i);
            //if(i == Find(i)){printf("i=%d,indegree=%d\n",i,indegree[i]);}
        }
        printf("Case %d ",++t);
        if(!flag && tp <= 1) printf("is a tree.\n");
        else printf("is not a tree.\n");
    }
    return 0;
}
View Code

 

hdu1856

当n等于0的时候,输出为1,虽然数组要10的七次方,但是仍可以用1325的方法解。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N (10000000+10)

int node[N];
int cnt[N];

int Find(int x)
{
    if(node[x]==x) return x;
    int y = Find(node[x]);
    node[x] = y;
    return y;
}

void Union(int a,int b)
{
    if(a==b) return;
    int x = Find(node[a]);
    int y = Find(node[b]);
    if(x!=y)
    {
        node[x] = y;
    }
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<N;++i)
            node[i] = i,cnt[i] = 0;
        for(int i=0;i<n;++i)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            Union(a,b);
        }
        int MaxCnt = 1;
        for(int i=0;i<N;++i)
        {
            int y = Find(i);
            ++cnt[y];
            MaxCnt = MaxCnt > cnt[y] ? MaxCnt : cnt[y];
        }
        printf("%d\n",MaxCnt);
    }
    return 0;
}
View Code