C-Sprache – Lanqiao Cup 2023, 14. Provinzwettbewerb, echte Frage – Baumfällung

Beschreibung der Frage

Gegeben sei ein Baum bestehend aus n Knoten und m sich nicht wiederholenden Paaren ungeordneter Zahlen (a1, b1), (a2, b2),

. . , (am, bm), wobei ai voneinander verschieden sind, bi voneinander verschieden sind, ai ≠ bj(1 ≤ i, j ≤ m).

Xiao Ming möchte wissen, ob er eine Kante am Baum so schneiden kann, dass für jedes (ai, bi) ai und bi nicht verbunden sind. Wenn ja, geben Sie die Nummer der Kante aus, die geschnitten werden soll (die Nummer beginnt). von 1 in der Reihenfolge der Eingabe). , andernfalls Ausgabe -1.

Eingabeformat

Geben Sie insgesamt n + m Zeilen ein, die erste Zeile besteht aus zwei positiven ganzen Zahlen n, m.

In den folgenden n − 1 Zeilen hat jede Zeile zwei positive ganze Zahlen xi und yi, die die beiden Endpunkte der i-ten Kante darstellen.

Die folgenden m Zeilen enthalten in jeder Zeile zwei positive ganze Zahlen ai und bi.

Ausgabeformat

Eine ganze Zahl pro Zeile stellt die Antwort dar. Bei mehreren Antworten wird diejenige mit der höchsten Zahl ausgegeben.

Beispieleingabe

6 2 1 2 2 3 4 3 2 5 6 5 3 6 4 5 4

Beispielausgabe

4

Hinweis

Nach dem Trennen der zweiten Kante werden zwei verbundene Blöcke gebildet: {3, 4}, {1, 2, 5, 6}, die erfüllen, dass 3 und 6 nicht verbunden sind und 4 und 5 nicht verbunden sind.

Nach dem Trennen der vierten Kante werden zwei verbundene Blöcke gebildet: {1, 2, 3, 4}, {5, 6}, die auch erfüllen, dass 3 und 6 nicht verbunden sind und 4 und 5 nicht verbunden sind.

4 ist die höhere Zahl, daher lautet die Antwort 4.

Für 30 % der Daten ist 1 < n ≤ 1000 garantiert.

Für 100 % der Daten ist garantiert, dass 1 < n ≤ 105, 1 ≤ m ≤ 2/n.

Lösung:

#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include<functional>
#include <math.h>
#include <algorithm>
#include<unordered_map>
#include<ctime>
#include <cstring>
#define lowbit(x) (-x) & x
#define ll long long
const int N = 3e6;
using namespace std;    
const int mod = 1e9 + 7;
ll __pow(ll x,ll y){
  ll res = 1;
  while(y){
      if(y&1)res = (res * x);
      y>>=1;
      x = (x * x);
  }
  return res;
}
ll cal(ll v1, ll v2){
  return v1*__pow(v2,mod-2)%mod;
}
ll C(ll x,ll y){
  ll res = 1;
  for(int i = 1,j = x + 1; j <= y;j++, i++){
      res*=j;
      res/=i;
  }
  return res;
}
ll gcd(ll x, ll y){
  if(y == 0)return x;
  else return gcd(y, x%y);
}
struct node{
  int to,nxt,c = 0,idx;
}e[N];
int cnt = 0;
int head[N];
void add(int u, int v){
  e[++cnt].nxt = head[u];
  e[cnt].to = v;
  head[u] = cnt;
  e[cnt].c = 0;
  e[cnt].idx = (cnt + 1)/2;
}
void solve(){   
  int n,m;
  cin>>n>>m;
  for(int i = 0; i < n - 1; ++i){
      int u,v;
      cin>>u>>v;
      u--,v--;
      add(u, v);
      add(v, u);
  }
  map<ll,int>lca;
  vector<int>query[n];
  for(int i = 0; i < m;++i){
      int u, v;
      cin>>u>>v;
      u--, v--;
      query[u].push_back(v);
      query[v].push_back(u);
  } 
  int p[n];
  int f[n];
  vector<int>diff(n, 0);
  vector<int>color(n, 0);
  for(int i = 0; i < n;++i)f[i] = i;
  function<int(int)>find = [&](int x)->int{return (f[x] == x)?x : f[x] = find(f[x]);};
  function<void(int,int)>tarjan = [&](int u,int fa){
      color[u] = 1;
      p[u] = fa;
      for(int i = head[u];i ; i = e[i].nxt){
          int v = e[i].to;
          if(color[v]==0){
              tarjan(v, u);
              f[v] = u;
          }
      }
      for(int v : query[u]){
          if(color[v]==2 || u == v){
              int ffa = find(v);
              diff[u]++;
              diff[v]++;
              lca[(ll)u*(1ll<<32) + v] = ffa;
              lca[(ll)v*(1ll<<32) + u] = ffa;
              diff[ffa]-=2;
          }
      }
      color[u] = 2;
  };
  tarjan(0, -1);
  int maxe = -1;
  function<void(int,int)>dfs = [&](int u, int fa){
      for(int i = head[u];i; i = e[i].nxt){
          int v = e[i].to;
          if(v == fa)continue;
          dfs(v, u);
          int id = e[i].idx;
          diff[u] += diff[v];    
          if(diff[v] == m){
              maxe = max(maxe, id);
          }
      }   
  };
  dfs(0, -1);
  cout<<maxe<<endl;
}   
int main(){ 
  ios::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int t;
  t = 1;
  while(t--){
      solve();
  }
  return 0 ;
}

Guess you like

Origin blog.csdn.net/Joy19981127/article/details/135407824