[ SHOI 2015 ] 零件组装机
题目
思路
代码
貌似在 \(Acwing\) 上要吸臭氧
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int N = 100010;
set<int> G[N];
int T, fa[N], id[N], sz[N], cnt, now;
bool cmp(int a, int b) { return sz[a] < sz[b]; }
inline bool check(int a, int b, int c, int d) {
int n = b - a + 1, m = d - c + 1;
if (n > m) return false;
for (int i = 0; i < m; i++) {
int x = a + i % n, y = c + i;
if (G[y].find(x) == G[y].end()) return false;
else now++;
}
return true;
}
int main() {
cin >> T;
for (int n, m; T--; ) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) G[i].clear();
memset(fa, 0, sizeof fa), memset(sz, 0, sizeof sz);
cnt = 0, now = 0;
bool flag = true;
for (int a, b; m--; ) {
scanf("%d%d", &a, &b);
if (a > b) swap(a, b);
if (a == b || G[b].find(a) != G[b].end()) flag = false;
else G[b].insert(a), cnt++; // 这里反着连边
}
for (int i = 1; i < n && flag; i++) {
if (G[i].empty()) flag = false;
else fa[i] = *G[i].rbegin();
}
for (int i = 0; i < n; i++) sz[i] = 1;
for (int i = n - 1; i >= 1; i--) sz[fa[i]] += sz[i];
for (int i = 0; i < n; i++) id[i] = i;
sort(id, id + n, cmp);
for (int i = 0; i < n - 1 && flag; i++) {
int u = fa[id[i]], v = id[i];
if (!check(u, v - 1, v, v + sz[v] - 1)) flag = false;
}
if (flag && cnt == now) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}