P11252 [KTSC 2024 R2] 岛屿
EuphoricStar · · 题解
被诈骗了。
首先原来有
操作一次后有
答案是可以。我们可以选一个边上的小三角形进行操作。然后构造可以每次删除度数为
可以证明点数
时间复杂度
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;
int add_vertex(int, int, int);
void report(vector< array<int, 2> >);
const int maxn = 200100;
int n, deg[maxn];
bool vis[maxn];
vector<int> G[maxn];
void construct_two_trees(int _n, vector<int> _u, vector<int> _v) {
n = _n;
for (int i = 0; i < n; ++i) {
G[i].pb((i + 1) % n);
G[(i + 1) % n].pb(i);
}
for (int i = 0; i < n - 3; ++i) {
int u = _u[i], v = _v[i];
G[u].pb(v);
G[v].pb(u);
}
for (int i = 0; i < n; ++i) {
deg[i] = (int)G[i].size();
}
vector< array<int, 2> > A, B;
for (int u = 0; u < n; ++u) {
if (deg[u] == 2) {
int v = (u + n - 1) % n, w = (u + 1) % n;
add_vertex(u, v, w);
G[u].pb(n);
G[n].pb(u);
G[v].pb(n);
G[n].pb(v);
G[w].pb(n);
G[n].pb(w);
A.pb(array<int, 2>{u, v});
A.pb(array<int, 2>{v, w});
A.pb(array<int, 2>{w, n});
B.pb(array<int, 2>{u, w});
B.pb(array<int, 2>{u, n});
B.pb(array<int, 2>{v, n});
break;
}
}
queue<int> q;
for (int i = 0; i < n; ++i) {
deg[i] = (int)G[i].size();
if (deg[i] == 2) {
q.push(i);
}
}
while (q.size()) {
int u = q.front();
q.pop();
if (vis[u]) {
continue;
}
vis[u] = 1;
int v = 0, w = 0;
for (int x : G[u]) {
if (!vis[x]) {
(v ? w : v) = x;
if ((--deg[x]) == 2) {
q.push(x);
}
}
}
A.pb(array<int, 2>{u, v});
B.pb(array<int, 2>{u, w});
}
report(A);
report(B);
}