7999: 路径图 并查集
描述
给定一个n个顶点(1~n编号),m条边的简单无向图,判断是否是一个路径图。
路径图要求:必须存在一个顶点序列v1, v2, ..., vn,它是1~n的一个排列,且对于任何1<=i<=n-1,vi和vi+1之间有边相连,而对于任何1<=i, j<=n(其中|i-j|>=2),vi和vj之间没有边相连。
输入
第一行为两个正整数n和m(2<=n<=2*105, 0<=m<=2*105)。
接下来有m行,每行两个整数u和v(1<= u, v<= n),表示u和v之间有一条边。
输出
如果图是“路径图”输出Yes,否则输出No
路径图:可以理解为m条边刚好构成了一颗树,n个点之间连接了n-1条边,有回路不行,且每个点都要有边相连
通过并查集如果find(x)==find(y)那么就是有回路,通过并查集后的f[i]==i来统计父节点的个数,如果大于1那么也不行
#include<bits/stdc++.h> using namespace std; const int N = 2e5+10; int f[N]; int find(int x) { if(f[x]!=x)f[x] = find(f[x]); return f[x]; } void merge(int x,int y) { int fx = find(x); int fy = find(y); f[fy] = fx; } int main() { int n,m,flag = 1; cin >> n >> m; for(int i=1;i<=n;i++)f[i] = i; for(int i=1;i<=m;i++) { int x,y; scanf("%d %d",&x,&y); if(find(x)!=find(y))merge(x,y); else flag = 0; } int sum = 0; for(int i=1;i<=n;i++) if(f[i]==i)sum++; if(sum>1 || !flag)cout << "No"; else cout << "Yes"; return 0; }