結果
| 問題 |
No.2678 Minmax Independent Set (Hack)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-02-11 20:18:05 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,031 bytes |
| コンパイル時間 | 2,720 ms |
| コンパイル使用メモリ | 261,244 KB |
| 実行使用メモリ | 12,072 KB |
| 最終ジャッジ日時 | 2024-09-29 23:01:56 |
| 合計ジャッジ時間 | 3,298 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | WA * 1 |
ソースコード
#include <bits/stdc++.h>
struct RNG {
void setSeed(uint64_t seed) {
seedSet = true;
x = seed;
}
template <class T>
T choice(std::vector<T>& v) {
assert(!v.empty());
return v[range(0, (int)v.size() - 1)];
}
template <class T>
void shuffle(std::vector<T>& v) {
const int N = v.size();
for (int i = 0; i < N - 1; i++) {
const int j = range(i, N - 1);
if (i == j) continue;
std::swap(v[i], v[j]);
}
}
// generate random integers in [from, to]
template <class T, class U>
typename std::common_type<T, U>::type range(T from, U to) {
static_assert(std::is_integral_v<T>);
static_assert(std::is_integral_v<U>);
static_assert(std::is_integral_v<typename std::common_type<T, U>::type>);
assert(from <= to);
uint64_t width = to - from + 1;
typename std::common_type<T, U>::type ret = from;
ret += xorshift64() % width;
return ret;
}
private:
bool seedSet = false;
uint64_t x;
uint64_t xorshift64() {
assert(seedSet);
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
}
} rng;
// 辺を 1 箇所張り替えて非連結にする
using namespace std;
//----NokonoKotlin library : UnionFind(n) , nは要素数-----
class UnionFind {
private:
vector<long long> par;
public:
int Size;
vector<long long> rank; // rankが高いほど上の親である
vector<long long> size;
// 配列の中身は0 ~ N-1
UnionFind() {}
UnionFind(long long N) : rank(N), size(N) {
Size = N;
par.resize(N);
for (int i = 0; i < Size; i++) par[i] = i;
for (int i = 0; i < Size; i++) rank[i] = 0;
for (int i = 0; i < Size; i++) size[i] = 1;
}
~UnionFind() {
Release();
}
void Release() {
if (par.size() == 0) {
return;
}
}
int root(int x) {
if (par[x] == x)
return x;
else {
par[x] = root(par[x]);
return par[x];
}
}
void unite(int x, int y) {
int rx = root(x);
int ry = root(y);
int S = size[ry] + size[rx];
if (rx == ry) return;
if (rank[rx] < rank[ry]) {
par[rx] = ry; // rankの高い方を親にする
size[rx] = S;
size[ry] = S;
} else {
par[ry] = rx;
size[ry] = S;
size[rx] = S;
if (rank[rx] == rank[ry]) rank[rx]++;
}
}
int getsize(int x) {
return size[root(x)];
}
bool same(int x, int y) {
int rx = root(x);
int ry = root(y);
return rx == ry;
}
};
int main(int argc, char* argv[]) {
rng.setSeed(372864312);
int N = 100000;
vector<pair<int, int>> edges;
vector<int> prufer(N - 1);
for (int i = 0; i < N - 2; i++) prufer[i] = rng.range(1, N - 1);
prufer.back() = N;
multiset<int> cands;
for (int x = 1; x <= N; x++) cands.insert(x);
for (int x : prufer) cands.erase(x);
vector<int> cnt(N + 1, 0);
for (int x : prufer) cnt[x]++;
for (int x : prufer) {
int child = *cands.begin();
edges.emplace_back(x, child);
cands.erase(child);
cnt[x]--;
if (cnt[x] == 0) cands.insert(x);
}
UnionFind T(N + 1);
// どこかで切って 2 つの連結成分にする
edges.erase(edges.begin() + int(edges.size()) / 2);
for (auto p : edges) T.unite(p.first, p.second);
cout << N << endl;
// 片方をなもりグラフにして終了
for (int x = 1; x < N; x++) {
for (int y = x + 1; y <= N; y++) {
if (T.same(x, y)) {
edges.emplace_back(x, y);
for (pair<int, int> p : edges) cout << min(p.first, p.second) << " " << max(p.first, p.second) << "\n";
return 0;
}
}
}
return 0;
}