Submission #1279694

#TimeUsernameProblemLanguageResultExecution timeMemory
1279694nmhungLOSTIKS (INOI20_lostiks)C++20
100 / 100
1230 ms202028 KiB
#include <bits/stdc++.h> using namespace std; mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count()); #define TIME (1.0 * clock() / CLOCKS_PER_SEC) #define rf if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout);} //#define in ({int x = 0; int c = getchar(), n = 0; for(; !isdigit(c); c = getchar()) n = (c == '-'); for(; isdigit(c); c = getchar()) x = x * 10 + c - '0'; n ? -x : x;}) #define bit(i, mask) (((mask) >> (i)) & 1) #define on(i, mask) ((mask) | (1LL << (i))) #define off(i, mask) ((mask) & (~(1LL << (i)))) #define ll long long #define fi first #define se second #define pii pair<int, int> #define vi vector<int> #define all(a) (a).begin(), (a).end() #define len(x) ((int)(x).size()) #define pb push_back #define endl '\n' #define name "treemaze" template<typename T1, typename T2> bool mini(T1 &a, T2 b) {if(a > b) a = b; else return 0; return 1;} template<typename T1, typename T2> bool maxi(T1 &a, T2 b) {if(a < b) a = b; else return 0; return 1;} const int mod = 1e9 + 7; const int inf = 1e9 + 9; const ll oo = 1e18l + 7; const int M = 5e5 + 6; const int N = 1e6 + 6; const int LOG = 31 - __builtin_clz(N); int n, m, S, T; vector<pii> adj[N]; int key[50], node[50], h[N], val[N], go[N]; int par[N], sz[N], id[N], head[N], cnt = 0; int tin[N], tout[N], cntDfs = 0; int dp[1 << 20][20]; void inp(){ cin >> n >> S >> T; m = 0; for(int i = 1; i < n; i++){ int u, v, h; cin >> u >> v >> h; int w = 0; if(h){ w = (1 << m); key[m] = h; node[m << 1] = u; node[m << 1 | 1] = v; m++; } adj[u].pb({v, w}); adj[v].pb({u, w}); } } void dfs(int u, int pre){ sz[u] = 1; tin[u] = ++cntDfs; for(auto it : adj[u]){ int v = it.fi, w = it.se; if(v == pre) continue; par[v] = u; h[v] = h[u] + 1; val[v] = val[u] ^ w; dfs(v, u); sz[u] += sz[v]; } tout[u] = cntDfs; } void Hld(int u, int pre, int top){ id[u] = ++cnt; head[u] = top; int nxt = -1; for(auto it : adj[u]){ int v = it.fi; if(v == pre) continue; if(nxt == -1 || sz[nxt] < sz[v]) nxt = v; } if(nxt == -1) return; Hld(nxt, u, top); for(auto it : adj[u]){ int v = it.fi; if(v == pre || v == nxt) continue; Hld(v, u, v); } } int lca(int u, int v){ while(head[u] != head[v]){ if(id[head[u]] > id[head[v]]) swap(u, v); v = par[head[v]]; } return (h[u] > h[v]) ? v : u; } int dist(int u, int v){ return h[u] + h[v] - 2 * h[lca(u, v)]; } bool insub(int u, int v){ return tin[u] <= tin[v] && tout[v] <= tout[u]; } bool canGo(int u, int v, int mask){ int nmask = val[v] ^ val[u]; return ((nmask & mask) == nmask); } void proc(){ dfs(1, 1); Hld(1, 1, 1); if(canGo(S, T, 0)){ cout << dist(S, T) << endl; return; } for(int i = 0; i < m; i++){ int u = node[i << 1], v = node[i << 1 | 1]; if(h[u] > h[v]) swap(u, v); go[i] = insub(v, S) ? v : u; } for(int mask = 0; mask < (1 << m); mask++) for(int i = 0; i < m; i++) dp[mask][i] = inf; for(int i = 0; i < m; i++){ if(canGo(S, key[i], 0) && canGo(key[i], go[i], 0)) dp[1 << i][i] = dist(S, key[i]) + dist(key[i], go[i]); } for(int mask = 0; mask < (1 << m); mask++){ for(int i = 0; i < m; i++){ if(dp[mask][i] == inf) continue; for(int j = 0; j < m; j++){ if(bit(j, mask)) continue; if(canGo(go[i], key[j], mask) && canGo(key[j], go[j], mask)) mini(dp[mask | (1 << j)][j], dp[mask][i] + dist(go[i], key[j]) + dist(key[j], go[j])); } } } int ans = inf; for(int mask = 0; mask < (1 << m); mask++){ for(int i = 0; i < m; i++){ if(dp[mask][i] == inf) continue; if(canGo(go[i], T, mask)) mini(ans, dp[mask][i] + dist(go[i], T)); } } cout << (ans == inf ? -1 : ans); } int main(){ cin.tie(nullptr)->sync_with_stdio(false); rf int test = 1; //cin >> test; while(test--){ inp(); proc(); } cerr << "Time elapsed: " << TIME << "s" << endl; return 0; }

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:8:47: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
    8 | #define rf if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout);}
      |                                        ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:163:5: note: in expansion of macro 'rf'
  163 |     rf
      |     ^~
Main.cpp:8:80: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
    8 | #define rf if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout);}
      |                                                                         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:163:5: note: in expansion of macro 'rf'
  163 |     rf
      |     ^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...