| 森林木 | ||||||
| ||||||
| Description | ||||||
|
什么是一棵树?Something like A. 什么是一片森林?Something like B. 如果你依旧不理解, please go to baidu.
| ||||||
| 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");
}
}
}
}
本文介绍了一个算法问题,通过输入顶点和边来判断给定的图结构是否为树、森林或一般图。使用并查集的方法解决该问题,并提供了完整的C++代码实现。



1856

被折叠的 条评论
为什么被折叠?



