哈理工OJ 1959 森林木(并查集)

森林木
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 85(36 users) Total Accepted: 38(32 users) Rating:  Special Judge: No
Description

什么是一棵树?Something like A.

什么是一片森林?Something like B.

如果你依旧不理解, please go to baidu.

哈理工OJ 1959 森林木(并查集)_第1张图片
        

Input

本题有多组测试数据,每组数据第一行输入两个整数n和m,n代表有多少个点,m代表有m条无向边,接下来m行分别是m条边,题目保证无重边,无自环(即a走到a)。

(1≤n≤10000,1≤m≤1000000)

Output

对于每组测试数据输出结果,如果是一棵树,请输出“This is a tree.”,如果是一片森林,请输出“This is a forest.”,如果既不是森林也不是树,请输出“This is a graph.”。每组输出占一行。

Sample Input
3 2
1 2
2 3
4 4
1 2
2 3
3 1
1 4
Sample Output
This is a tree.
This is a graph.
Source
"科林明伦杯"哈尔滨理工大学第三届ACM程序设计团队预选赛

这是我们学长某一届的校团队赛的预选赛。思路还是很好建立的,如果对于大神来说这就是一个拼手速的题目吧~。

这里我们知道,如果自环了,那么就什么也不是,否则如果有一个父节点就是一棵树,如果大于一个父节点,那么说明就是森林了~

 #include<stdio.h>
#include<string.h>
using namespace std;
int flag;
int f[12121212];
void init(int n)
{
    for(int i=1;i<=n;i++)
    f[i]=i;
    flag=0;
}
int find(int x)
{
    return f[x] == x ? x : (f[x] = find(f[x]));
}
void merge(int a,int b)
{
    int A,B;
    A=find(a);
    B=find(b);
    if(A!=B)
    f[B]=A;
    else flag=1;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        init(n);
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            merge(x,y);
        }
        if(flag==1)
        printf("This is a graph.\n");
        else
        {
            int cont=0;
            for(int i=1;i<=n;i++)
            {
                if(f[i]==i)
                cont++;
            }
            if(cont==1)
            {
                printf("This is a tree.\n");
            }
            else
            {
                printf("This is a forest.\n");
            }
        }
    }
}









你可能感兴趣的:(哈理工OJ1959)