4216. 图中的环
作者:互联网
题目链接
4216. 图中的环
给定一个 \(n\) 个点 \(m\) 条边的无向图。
点的编号从 \(1\) 到 \(n\)。
图中不含重边和自环。
请你对给定图进行判断,如果该图是一个有且仅有一个环的连通图,则输出 YES
,否则输出 NO
。
输入格式
第一行包含两个整数 \(n,m\)。
接下来 \(m\) 行,每行包含两个整数 \(a,b\),表示点 \(a\) 和点 \(b\) 之间存在一条无向边。
输出格式
如果该图是一个有且仅有一个环的连通图,则输出 YES
,否则输出 NO
。
数据范围
前三个测试点满足 \(1≤n≤10\)。
所有测试点满足 \(1≤n≤100\),\(0≤m≤
\frac{n(n−1)}{2}\),\(1≤a,b≤n\)。
输入样例1:
6 6
6 3
6 4
5 1
2 5
1 4
5 4
输出样例1:
YES
输入样例2:
6 5
5 6
4 6
3 1
5 1
1 2
输出样例2:
NO
解题思路
基环树
一棵树为基环树的充要条件:
- 连通
- 点数=边数
显然,题目要求的便是判断一棵树是否为基环树,点数=边数可以直接判断,连通可用并查集判断
- 时间复杂度:\(O(nlogn)\)
代码
// Problem: 图中的环
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/4219/
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// %%%Skyqwq
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
int n,m,fa[105];
int get(int x)
{
return x==fa[x]?x:fa[x]=get(fa[x]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
fa[get(a)]=get(b);
}
if(n!=m)puts("NO");
else
{
int p=-1;
for(int i=1;i<=n;i++)
if(p==-1)p=get(i);
else if(p!=get(i))
{
puts("NO");
return 0;
}
puts("YES");
}
return 0;
}
标签:输出,连通,4216,int,样例,fa,图中,define 来源: https://www.cnblogs.com/zyyun/p/15855941.html