結果
問題 | No.2987 Colorful University of Tree |
ユーザー |
👑 ![]() |
提出日時 | 2024-12-02 00:47:49 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 330 ms / 5,000 ms |
コード長 | 5,571 bytes |
コンパイル時間 | 1,725 ms |
コンパイル使用メモリ | 133,044 KB |
最終ジャッジ日時 | 2025-02-26 10:25:06 |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 42 |
ソースコード
#include <iostream>#include <vector>#include <algorithm>#include <utility>#include <set>#include <unordered_map>#include <cassert>#include <cstdint>#include <array>class Xoshiro256pp{public:using i64 = long long;using u64 = unsigned long long;private:std::array<u64, 4> s;static inline uint64_t rotl(const uint64_t x, int k) noexcept {return (x << k) | (x >> (64 - k));}inline uint64_t gen(void) noexcept {const uint64_t result = rotl(s[0] + s[3], 23) + s[0];const uint64_t t = s[1] << 17;s[2] ^= s[0];s[3] ^= s[1];s[1] ^= s[2];s[0] ^= s[3];s[2] ^= t;s[3] = rotl(s[3], 45);return result;}public:Xoshiro256pp(){s[0] = 0x8e1281ee837ab726;s[1] = 0xbe54f8d4f619af0d;s[2] = 0x0d989b2579a56e23;s[3] = 0x7b3c16005b6dddf9;}u64 rng64() { return gen(); }// generate x : l <= x <= ru64 random_unsigned(u64 l,u64 r){assert(l<=r);r-=l;auto res = rng64();if(res<=r) return res+l;u64 d = r+1;u64 max_valid = 0xffffffffffffffff/d*d;while(true){auto res = rng64();if(res<=max_valid) break;}return res%d+l;}};using namespace std;#define rep(i,n) for(int i=0; i<int(n); i++)pair<int, vector<int>> bin_packing(vector<int> weight){int N = weight.size();int N_original = N;int odd_count = 0;for(int a : weight) if(a % 2 == 1) odd_count += 1;int sum = N * 2 - 2;int Q = *max_element(weight.begin(), weight.end());;while(true){int req = sum;if(Q % 2 == 1) req += max(0, Q - odd_count);if(req <= (long long)Q * Q) break;Q += 1;}int P = (sum + Q - 1) / Q;if(P < Q) P += 1;while(sum < P*Q){weight.push_back(1);sum += 1;N += 1;odd_count += 1;}set<pair<int,int>> even_group, odd_group;rep(i,N) (weight[i] % 2 ? odd_group : even_group).insert({ -weight[i], i });even_group.insert({ 1, -100 });odd_group.insert({ 1, -100 });vector<int> ans(N, -1);auto set_ans = [&](int i, int c){if(i < 0) exit(1);(weight[i] % 2 ? odd_group : even_group).erase({ -weight[i], i });ans[i] = c;if(weight[i] % 2 == 1) odd_count -= 1;};auto extract_max_at = [&](set<pair<int,int>>& src, int x){pair<int,int> res = *src.lower_bound({ -x, -1 });res.first *= -1;return res;};auto extract_max = [&](int x){return max(extract_max_at(even_group, x), extract_max_at(odd_group, x));};rep(i,P){int to_pack = Q;if(Q % 2 == 1){if(odd_count == P - i){auto [w,v] = extract_max_at(odd_group, to_pack);set_ans(v, i);to_pack -= w;}while(to_pack > 0){auto [w,v] = (odd_count == P-i-1) ? extract_max_at(even_group, to_pack) : extract_max(to_pack);set_ans(v, i);to_pack -= w;}} else {while(to_pack > 0){auto [w,v] = extract_max(to_pack);set_ans(v, i);to_pack -= w;}}}ans.resize(N_original);return {Q,ans};}#include <random>#include <chrono>void testcase(){// inputint N; cin >> N;vector<vector<int>> edges(N);rep(i,N){int c; cin >> c;rep(j,c){int e; cin >> e; e--;edges[i].push_back(e);}}// node colorvector<int> deg(N);rep(i,N) deg[i] = edges[i].size();auto [Q, vcolor] = bin_packing(deg);// heuristicvector<int> bedge(N*2-2);vector<int> eVisCount(N-1, 0);rep(i,N) rep(j,edges[i].size()){int e = edges[i][j];bedge[e*2 + eVisCount[e]] = vcolor[i];edges[i][j] = e*2 + eVisCount[e];eVisCount[e]++;}Xoshiro256pp rng;vector<int> vacant(Q, 0);vector<int> bcolor(N*2-2);rep(e,N*2-2) bcolor[e] = vacant[bedge[e]]++;vector<vector<int>> maps(Q);rep(q,Q) maps[q].resize(vacant[q]+1);rep(e,N*2-2) maps[bedge[e]][bcolor[e]] = e;vector<int> conflict;rep(i,N-1) if(bcolor[i*2] == bcolor[i*2+1]) conflict.push_back(i);while(conflict.size()){int ex = conflict.back(); conflict.pop_back();int e0 = ex * 2 + 0;int e1 = ex * 2 + 1;if(bcolor[e0] != bcolor[e1]) continue;if(vacant[bedge[e0]] != Q){swap(vacant[bedge[e0]], bcolor[e0]);continue;}if(vacant[bedge[e1]] != Q){swap(vacant[bedge[e1]], bcolor[e1]);continue;}int f = (int)rng.random_unsigned(0, 2*(Q-1) - 1);if(f >= Q-1){ swap(e0, e1); f -= Q-1; }if(f >= bcolor[e0]) f++;int vcol = bedge[e0];int e0x = maps[vcol][f];swap(bcolor[e0x], bcolor[e0]);swap(maps[vcol][f], maps[vcol][bcolor[e0]]);if(bcolor[e0x] == bcolor[e0x^1]){conflict.push_back(e0x / 2);}}// outputcout << Q << '\n';rep(i,N){cout << (vcolor[i] + 1);for(auto e : edges[i]) cout << ' ' << (bcolor[e] + 1);cout << '\n';}}int main(){ios::sync_with_stdio(false); cin.tie(nullptr);int T; cin >> T;rep(ti,T) testcase();return 0;}