题目链接:
首先根据条件 $- 对于所有 i=1,2,…,N−1,有一条边连接顶点 v_i $ 和 \(v_{i+1}\)
可以得到,路径图必须有 \(N-1\) 条边。
其次, If integers \(i\) and \(j\) satisfies \(1 \leq i, j \leq N\) and \(|i - j| \geq 2\), then there is no edge that connects vertices \(v_i\) and \(v_j\).
由此可以得到,该无向图中没有环,且是有着 \(N-1\) 条边的连通图。也即这是一条链。以后可以直接记住这个结论
使用并查集判断连通,并且图中只有两个度为 \(1\) 的结点,其余结点度都为 \(2\) 即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int p[N], d[N];
int find(int x) {
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
int n, m, c1, c2;
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= n; i++) p[i] = i;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
d[u] += 1, d[v] += 1;
p[find(u)] = find(v);
}
for (int i = 2; i <= n; i++) {
if (find(i) != find(1)) {
cout << "No\n";
return 0;
}
}
for (int i = 1; i <= n; i++) {
if (d[i] == 1) c1 ++;
if (d[i] == 2) c2 ++;
}
if (c1 == 2 && c2 == n - 2) cout << "Yes";
else cout << "No";
return 0;
}
附上 \(\rm jiangly\) 的代码,便于学习:
#include <bits/stdc++.h>
using i64 = long long;
struct DSU {
std::vector<int> f, siz;
DSU(int n) : f(n), siz(n, 1) { std::iota(f.begin(), f.end(), 0); }
int leader(int x) {
while (x != f[x]) x = f[x] = f[f[x]];
return x;
}
bool same(int x, int y) { return leader(x) == leader(y); }
bool merge(int x, int y) {
x = leader(x);
y = leader(y);
if (x == y) return false;
siz[x] += siz[y];
f[y] = x;
return true;
}
int size(int x) { return siz[leader(x)]; }
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int N, M;
std::cin >> N >> M;
if (M != N - 1) {
std::cout << "No\n";
return 0;
}
std::vector<int> deg(N);
DSU dsu(N);
for (int i = 0; i < M; i++) {
int u, v;
std::cin >> u >> v;
u--, v--;
deg[u]++, deg[v]++;
dsu.merge(u, v);
}
for (int i = 0; i < N; i++) {
if (deg[i] > 2) {
std::cout << "No\n";
return 0;
}
if (!dsu.same(i, 0)) {
std::cout << "No\n";
return 0;
}
}
std::cout << "Yes\n";
return 0;
}
标签:std,ABC,return,int,siz,cin,Path,leader,287
From: https://www.cnblogs.com/pangyou3s/p/18148699