Submission #1091742

#TimeUsernameProblemLanguageResultExecution timeMemory
1091742Zero_OPMin-max tree (BOI18_minmaxtree)C++14
0 / 100
1068 ms39248 KiB
#include<bits/stdc++.h> using namespace std; #define sz(v) (int)v.size() #define all(v) begin(v), end(v) #define compact(v) v.erase(unique(all(v)), end(v)) #define dbg(v) "[" #v " = " << (v) << "]" #define file(name) if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); } #define rep(i, l, r) for(int i = (l); i < (r); ++i) using ll = long long; using vi = vector<int>; using vl = vector<long long>; using ld = long double; template<typename T> bool minimize(T& a, const T& b){ if(a > b){ return a = b, true; } return false; } template<typename T> bool maximize(T& a, const T& b){ if(a < b){ return a = b, true; } return false; } template<int dimension, typename T> struct tensor : public vector<tensor<dimension - 1, T>> { static_assert(dimension > 0, "Dimension must be positive !\n"); template<typename... Args> tensor(int n = 0, Args... args) : vector<tensor<dimension - 1, T>> (n, tensor<dimension - 1, T>(args...)) {} }; template<typename T> struct tensor<1, T> : public vector<T> { tensor(int n = 0, T val = T()) : vector<T>(n, val) {} }; const int INF = 1e7 + 5; struct MaximumBipartiteMatching { int n; vector< vector<int> > ke; vector< bool > seen; vector< int > matchL, matchR; MaximumBipartiteMatching(int n) : n(n), ke(n), seen(n, false), matchL(n, -1), matchR(n, -1) {} void addEdge(int u, int v) { ke[u].push_back(v); } bool bpm(int u) { for(__typeof(ke[u].begin()) v = ke[u].begin(); v != ke[u].end(); ++v) { if (seen[*v]) continue; seen[*v] = true; if (matchR[*v] < 0 || bpm(matchR[*v])) { matchL[u] = *v; matchR[*v] = u; return true; } } return false; } int match() { int res = 0; for(int i = 0; i < n; ++i) { for(int i = 0; i < n; ++i) seen[i] = false; if (bpm(i)) ++res; } return res; } }; const int MAX = 7e4 + 5; const int inf = 1e9 + 7; int n, q, head[MAX], depth[MAX], sz[MAX], heavy[MAX], par[MAX], pos[MAX], timerHLD; vector<int> adj[MAX]; vector<pair<int, int>> addEdge[2][MAX], deleteEdge[2][MAX]; int minEdge[MAX], maxEdge[MAX]; void dfs(int u){ sz[u] = 1; for(int v : adj[u]){ adj[v].erase(find(all(adj[v]), u)); depth[v] = depth[u] + 1; par[v] = u; dfs(v); sz[u] += sz[v]; if(sz[heavy[u]] < sz[v]){ heavy[u] = v; } } } void dfsHLD(int u, int chain){ head[u] = chain; if(heavy[u]){ dfsHLD(heavy[u], chain); for(int v : adj[u]){ if(v != heavy[u]){ dfsHLD(v, v); } } } } int getLCA(int u, int v){ while(head[u] != head[v]){ if(depth[head[u]] < depth[head[v]]) swap(u, v); u = par[head[u]]; } return (depth[u] < depth[v] ? u : v); } int queries[MAX]; multiset<pair<int, int>> st[2][MAX]; void dfs_solve(int u){ for(int v : adj[u]){ dfs_solve(v); for(int i = 0; i < 2; ++i){ if(sz(st[i][u]) < sz(st[i][v])){ swap(st[i][u], st[i][v]); } for(auto it : st[i][v]) st[i][u].insert(it); } } for(int i = 0; i < 2; ++i){ for(auto it : addEdge[i][u]) st[i][u].insert(it); for(auto it : deleteEdge[i][u]){ st[i][u].erase(st[i][u].lower_bound(it)); st[i][u].erase(st[i][u].lower_bound(it)); } } minEdge[u] = (st[0][u].empty() ? -1 : st[0][u].begin() -> second); maxEdge[u] = (st[1][u].empty() ? -1 : st[1][u].rbegin() -> second); } void testcase(){ cin >> n; for(int i = 1; i < n; ++i){ int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } dfs(1); dfsHLD(1, 1); cin >> q; for(int i = 1; i <= q; ++i){ char op; int u, v, w; cin >> op >> u >> v >> w; int type = (op == 'm' ? 0 : 1); int lca = getLCA(u, v); addEdge[type][u].push_back({w, i}); addEdge[type][v].push_back({w, i}); deleteEdge[type][lca].push_back({w, i}); //remember x2 times queries[i] = w; } dfs_solve(1); MaximumBipartiteMatching Match(n + q + 1); for(int i = 2; i <= n; ++i){ if(minEdge[i] != -1){ Match.addEdge(i, n + minEdge[i]); } if(maxEdge[i] != -1){ Match.addEdge(i, n + maxEdge[i]); } } int ret = Match.match(); vector<int> resEdge(n + 1); for(int i = 2; i <= n; ++i){ if(Match.matchL[i] >= 0){ resEdge[i] = queries[Match.matchL[i] - n]; } else{ resEdge[i] = inf; } } for(int i = 2; i <= n; ++i){ cout << par[i] << ' ' << i << ' ' << resEdge[i] << '\n'; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); file("task"); int T = 1; // cin >> T; while(T--){ testcase(); } return 0; }

Compilation message (stderr)

minmaxtree.cpp: In function 'void testcase()':
minmaxtree.cpp:192:9: warning: unused variable 'ret' [-Wunused-variable]
  192 |     int ret = Match.match();
      |         ^~~
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:9:55: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
    9 | #define file(name) if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
      |                                                ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
minmaxtree.cpp:211:5: note: in expansion of macro 'file'
  211 |     file("task");
      |     ^~~~
minmaxtree.cpp:9:88: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
    9 | #define file(name) if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
      |                                                                                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
minmaxtree.cpp:211:5: note: in expansion of macro 'file'
  211 |     file("task");
      |     ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...