Submission #668873

#TimeUsernameProblemLanguageResultExecution timeMemory
668873joelgun14Railway (BOI17_railway)C++17
100 / 100
271 ms48524 KiB
// header file #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> // pragma #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") // macros #define endl "\n" #define ll long long #define mp make_pair #define ins insert #define lb lower_bound #define pb push_back #define ub upper_bound #define lll __int128 #define fi first #define se second using namespace std; using namespace __gnu_pbds; typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset; const int lim = 1e5 + 5; int dep_cnt[lim]; struct disjoint_set { int head[lim], size[lim], ans[lim]; map<int, int> dep[lim]; disjoint_set() { memset(head, -1, sizeof(head)); fill(size, size + lim, 1); memset(ans, 0, sizeof(ans)); } int fh(int nd) { while(head[nd] != -1) nd = head[nd]; return nd; } bool merge(int x, int y) { x = fh(x), y = fh(y); if(x != y) { if(size[x] < size[y]) swap(x, y); size[x] += size[y], head[y] = x; for(auto i : dep[y]) { if(dep[x][i.fi]) { dep[x][i.fi] += i.se; if(dep[x][i.fi] == dep_cnt[i.fi]) --ans[x]; } else { dep[x][i.fi] += i.se; if(dep[x][i.fi] != dep_cnt[i.fi]) ++ans[x]; } } } return x != y; } }; vector<int> edges[lim], dep_nd[lim], ans; bool vis[lim]; int k, depth[lim]; disjoint_set dsu; void dfs(int nd) { vis[nd] = 1; for(auto i : dep_nd[nd]) { ++dsu.dep[nd][i]; if(dep_cnt[i] != 1) ++dsu.ans[nd]; } for(auto i : edges[nd]) { if(!vis[i]) depth[i] = depth[nd] + 1, dfs(i), dsu.merge(nd, i); } //cout << "ND " << nd << " " << dsu.ans[dsu.fh(nd)] << endl; if(dsu.ans[dsu.fh(nd)] >= k) ans.pb(nd); } int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); // have a tree, find which edges should be constructed // constructed edges -> use lca, using LCA, we can find what edges should be connected // LCA of adj edges // sol 2: // use subtree count // in each node, a par edge is used if not all the neighborhoods are in the subtree // use DSU On Tree, maintaining count of elements and amount of active // ez int n, m; cin >> n >> m >> k; vector<pair<int, int>> adj; for(int i = 1; i < n; ++i) { int u, v; cin >> u >> v; edges[u].pb(v); edges[v].pb(u); adj.pb(mp(u, v)); } for(int i = 1; i <= m; ++i) { int s; cin >> s; dep_cnt[i] = s; while(s--) { int x; cin >> x; dep_nd[x].pb(i); } } dfs(1); // yang child di fi // se jadi number for(int i = 0; i < adj.size(); ++i) { if(depth[adj[i].fi] < depth[adj[i].se]) swap(adj[i].fi, adj[i].se); adj[i].se = i + 1; } sort(adj.begin(), adj.end()); vector<int> res; for(auto i : ans) res.pb((*lower_bound(adj.begin(), adj.end(), mp(i, 0))).se); //cout << endl; sort(res.begin(), res.end()); cout << res.size() << endl; for(auto i : res) cout << i << " "; cout << endl; return 0; }

Compilation message (stderr)

railway.cpp: In function 'int main()':
railway.cpp:112:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  112 |     for(int i = 0; i < adj.size(); ++i) {
      |                    ~~^~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...