每日闲聊
睡太晚了,眼睛好累.
今天少肝一点.
题目大意
给出一个图,问是不是基环树.
给定数据
第一行是 n , m n,m n,m,表示 n n n个顶点和 m m m条边.
接下来是 m m m行,每行给出 a , b a,b a,b,表示一条 a , b a,b a,b之间的边.
保证为简单图.
输出要求
给出的图是基环树就输出FHTAGN!
,否则输出NO
.
(吐槽一下CF的奇妙输出.)
解题思路
模板题啊.
基环树的特点有啥,
- 顶点数量和边数相等.
好啦,它不是输入了顶点数和边数吗,我们先判断一下:
int main(){
cin>>n>>m;
if(n!=m){
puts("NO");
return 0;
}
要求整个图都是基环树对吧,那它必须得联通啊.
并查集是个好东西.我们可以得出所有顶点的fa
,根据并查集的内容,如果有一个顶点的fa
和fa[1]
不同就说明这个图不连通.
//实现准备
void init(){
for(int i=1;i<N;++i){
fa[i]=i;
rnk[i]=1;
}
}
int find(int a){
if(fa[a]==a) return a;
else{
fa[a]=find(fa[a]);
return fa[a];
}
}
void merge(int a,int b){
int x=find(a),y=find(b);
if(rnk[x]>=rnk[y]){
fa[y]=x;
}
else{
fa[x]=y;
}
if(rnk[x]==rnk[y]) ++rnk[x];
}
//主函数部分
init();
while(m--){
cin>>a>>b;
merge(a,b);
}
for(int i=2;i<=n;++i){
if(find(i)!=find(1)){
puts("NO");
return 0;
}
}
puts("FHTAGN!");
return 0;
}
整合一下就好了.
蒟蒻的AC代码
#include<bits/stdc++.h>
#define ll long long
const int N=1e2+5;
using namespace std;
int n,m,a,b;
int fa[N],rnk[N];
void init(){
for(int i=1;i<N;++i){
fa[i]=i;
rnk[i]=1;
}
}
int find(int a){
if(fa[a]==a) return a;
else{
fa[a]=find(fa[a]);
return fa[a];
}
}
void merge(int a,int b){
int x=find(a),y=find(b);
if(rnk[x]>=rnk[y]){
fa[y]=x;
}
else{
fa[x]=y;
}
if(rnk[x]==rnk[y]) ++rnk[x];
}
int main(){
cin>>n>>m;
if(n!=m){
puts("NO");
return 0;
}
init();
while(m--){
cin>>a>>b;
merge(a,b);
}
for(int i=2;i<=n;++i){
if(find(i)!=find(1)){
puts("NO");
return 0;
}
}
puts("FHTAGN!");
return 0;
}