欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Codeforces Round #835 (Div. 4) A-G Complete Problem Solving-G、

最编程 2024-03-10 13:59:11
...

首先,如果不能跳跃,那么肯定就是 \(S\)\(T\) 的链的异或值。
考虑跳跃。那么我们的路径就成为了以 \(S\)不越过 \(T\) 的一条链加上以 \(T\) 为起点的另外一条链。
为什么是链?因为走回头路相当于这一段是无效操作。
为什么 \(S\) 开始不能越过 \(T\)? 因为直接走路的话不能进 \(T\)
为什么 \(T\) 可以越过 \(S\)? 因为可以先去 \(S\) 的另外一棵子树,再去这一课子树。
上述操作也包含了不传送的情况。(原地TP)。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 100010
#define ll long long

struct node{
  int u, v, next;
  ll w; 
} t[N << 1];
int head[N];

int bian = 0;
inline void addedge(int u, int v, ll w){
  t[++bian] = (node){u, v, head[u], w}, head[u] = bian;
  return ; 
}

int n, S, T; 
map <ll, bool> g; 

ll dis1[N]; 
ll dis2[N]; 

bool vis1[N], vis2[N]; 
void dfs1(int u){
  if(u == T) return ; 
  vis1[u] = 1; 
  for(int i = head[u]; i; i = t[i].next){
    int v = t[i].v; 
    if(!vis1[v]){
      dis1[v] = dis1[u] ^ t[i].w; 
      dfs1(v); 
    }
  }
  return ; 
}

void dfs2(int u){
  // if(u == S) return ; 
  vis2[u] = 1; 
  for(int i = head[u]; i; i = t[i].next){
    int v = t[i].v; 
    if(!vis2[v]){
      dis2[v] = dis2[u] ^ t[i].w; 
      dfs2(v); 
    }
  }
  return ;
}

void clear(int n){

  g.clear(); 
  for(int i = 1; i <= n; i++)
    dis1[i] = dis2[i] = 0; 
  for(int i = 1; i <= n; i++)
    head[i] = 0, vis1[i] = vis2[i] = 0; 
  bian = 0; 
  return ; 
}

int main(){
  int testcase; cin >> testcase;
  while(testcase--){
    clear(n); 

    cin >> n >> S >> T; 
    for(int i = 1; i < n; i++){
      int u, v, w; 
      cin >> u >> v >> w;
      addedge(u, v, w);
      addedge(v, u, w); 
    }
    dfs1(S); 
    dfs2(T); 
    for(int i = 1; i <= n; i++)
      if(vis1[i]) g[dis1[i]] = 1; 
    bool flag = 0;  
    for(int i = 1; i <= n; i++){
      if(vis2[i] && i != T)
        if(g[dis2[i]] == 1){
         flag = 1;
         break; 
        } 
    }
    
    if(flag) puts("YES");
    else puts("NO"); 
  }
  return 0; 
}

原文地址:https://www.cnblogs.com/wondering-world/p/16919330.html