제출 #798398

#제출 시각아이디문제언어결과실행 시간메모리
798398PixelCatSimurgh (IOI17_simurgh)C++14
30 / 100
198 ms4020 KiB
#include "simurgh.h" #ifdef NYAOWO #include "grader.cpp" #endif #include <bits/stdc++.h> #define For(i, a, b) for(int i = a; i <= b; i++) #define Forr(i, a, b) for(int i = a; i >= b; i--) #define F first #define S second #define all(x) x.begin(), x.end() #define sz(x) ((int)x.size()) #define eb emplace_back // #define int LL using namespace std; using i32 = int32_t; using LL = long long; using pii = pair<int, int>; const int MAXN = 500; vector<pii> adj[MAXN + 10]; // { node, edge id } struct Tree { set<int> edge; set<int> suseid; set<int> egg; set<int> epote; int par[MAXN + 10]; int dep[MAXN + 10]; int peid[MAXN + 10]; bool good[MAXN + 10]; bool sussy[MAXN + 10]; vector<int> get_edges() { vector<int> ids; for(auto &i:edge) ids.eb(i); return ids; } int query() { // cerr << "query: "; // out(); return count_common_roads(get_edges()); } void dfs(int x, int p, int d, int pe, bool tree_edge_only = true) { if(p < 0) { memset(dep, 0, sizeof(dep)); } par[x] = p; dep[x] = d; peid[x] = pe; good[x] = !suseid.count(pe); sussy[x] = !good[x]; for(auto &i:adj[x]) if(i.F != p && dep[i.F] == 0) { if(tree_edge_only && !edge.count(i.S)) continue; else if(!tree_edge_only) { edge.insert(i.S); suseid.insert(i.S); } dfs(i.F, x, d + 1, i.S, tree_edge_only); good[x] = good[x] && good[i.F]; sussy[x] = sussy[x] && good[i.F]; } } void collect(int x, int p, set<int> &subtree) { subtree.insert(x); for(auto &i:adj[x]) if(i.F != p && edge.count(i.S)) { collect(i.F, x, subtree); } } void build_tree(int N) { For(_, 1, N - 1) { dfs(0, -1, 1, -1); // For(i, 0, N - 1) cerr << par[i] << " \n"[i == N - 1]; // For(i, 0, N - 1) cerr << peid[i] << " \n"[i == N - 1]; int x = -1; For(i, 0, N - 1) if(sussy[i]) x = i; assert(x >= 0); suseid.erase(peid[x]); int cnt; set<int> subtree; collect(x, par[x], subtree); vector<int> eids; for(auto &a:subtree) for(auto &e:adj[a]) { if(subtree.count(e.F) || egg.count(e.S)) continue; // if(epote.count(e.S)) { // edge.erase(peid[x]); // edge.insert(e.S); // goto FOUND; // } eids.eb(e.S); } cnt = query(); edge.erase(peid[x]); For(i, 0, sz(eids) - 1) { edge.insert(eids[i]); int cnt2 = query(); if(cnt < cnt2) { // For(j, 0, i - 1) egg.insert(eids[j]); // egg.insert(peid[x]); // epote.insert(eids[i]); goto FOUND; } else if(cnt > cnt2) { // For(j, 0, i - 1) epote.insert(eids[j]); // epote.insert(peid[x]); // egg.insert(eids[i]); edge.erase(eids[i]); edge.insert(peid[x]); goto FOUND; } edge.erase(eids[i]); } edge.insert(peid[x]); FOUND:; out(); } } void out() { #ifdef NYAOWO cerr << "tree: "; for(auto &i:get_edges()) { cerr << i << " "; } cerr << "\n"; #endif } } tr; vector<int> find_roads(int N, vector<int> U, vector<int> V) { int M = sz(U); For(i, 0, M - 1) { adj[U[i]].eb(V[i], i); adj[V[i]].eb(U[i], i); } tr.dfs(0, -1, 1, -1, false); tr.build_tree(N); return tr.get_edges(); // vector<int> r(n - 1); // for(int i = 0; i < n - 1; i++) // r[i] = i; // int common = count_common_roads(r); // if(common == n - 1) // return r; // r[0] = n - 1; // return r; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...