#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 >> m >> 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;
}
컴파일 시 표준 에러 (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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |