Problem: 2063C - Remove Exactly Two
Language: C++23 (GCC 14-64, msys2)

Previous submission (verdict: Wrong answer on test 2):

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define FASTIO() \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL);
using namespace std;

//<------------------------------------------------------------------------------------------------------------------------------------------------------------------------------>
//                                                            DEBUG TEMPLATE
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}

#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

// ordered set
// find_by_order, order_of_key
// order_of_key (k) : Number of items strictly smaller than k.
// find_by_order(k) : K-th element in a set (counting from zero)
using namespace __gnu_pbds;
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update> ;
template<class T> using ordered_multiset = tree<T, null_type,less_equal<T>, rb_tree_tag,tree_order_statistics_node_update>;
template<class key, class value, class cmp = std::less<key>> using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
struct pair_hash {
    template <class T1, class T2>
    size_t operator()(const std::pair<T1, T2>& p) const {
        auto h1 = std::hash<T1>{}(p.first);
        auto h2 = std::hash<T2>{}(p.second);
        return h1 ^ (h2 << 1);
    }
};
class DSU{
    public:
    vector<int> Rank, parent;
    void make(int n) {
        Rank.resize(n+1,0);
        parent.resize(n+1);
        for (int i = 0; i <= n; i++) {
            parent[i] = i;
        }
    }
    int get(int node) {
        if (node == parent[node])
            return node;
        return parent[node] = get(parent[node]);
    }
    void unite(int u, int v) {
        int ulp_u = get(u);
        int ulp_v = get(v);
        if (ulp_u == ulp_v) return;
        if (Rank[ulp_u] < Rank[ulp_v]) {
            parent[ulp_u] = ulp_v;
        }
        else if (Rank[ulp_v] < Rank[ulp_u]) {
            parent[ulp_v] = ulp_u;
        }
        else {
            parent[ulp_v] = ulp_u;
            Rank[ulp_u]++;
        }
    }
};
//<----------------------------------------------------------------------------------------------------------------------------------------------------------------------------->

// lets say in degree of u and v is du and dv.
// if u and v are adjacent (one is the parent of other) then components = du + dv - 2;
// if u and v are not adjacent then components = du + dv - 1;
// Now its very obvious we greedily try to remove the max value of du.
// Now if we have more one max of du, then it is very obvious that we take any two max values that are not adjacent.
// But there maybe also a case where there all max values are adjacent to each other.
// what we do is simply take any two nodes u and v with max value(if they exist) and brute all node w with (u,w) and (v,w) and then finally
// check for (u,v). Now it is guarenteed that at least one  pair in (u,v), (v,w) and (u,w) they will not be adjacent
// since if they were it would have beem a cycle which is not possible in a tree

int calc(int n, int node, set<vector<int>>edges, vector<int>&indegree){
    int ans = 0;
    for(auto it = edges.begin(); it != edges.end();){
        auto edge = *it;
        int u = edge[0], v = edge[1];
        if(u == node || v == node){
            it = edges.erase(it);
        }
        else{
            ++it;
        }
    }
    if(edges.empty()){
        return indegree[node] - 1;
    }

    DSU dsu;
    dsu.make(n + 1);
    for(auto &ele: edges){
        int u = ele[0], v = ele[1];
        dsu.unite(u, v);
    }
    debug(ans);
    for(int i = 1; i <= n; ++i){
        if(i == node) continue;
        if(dsu.parent[i] == node){
            debug(i, indegree[i]);
            int check = indegree[node] + indegree[i] - 2;
            ans = max(ans, check);
            debug(ans);
        }
        else{
            debug(i, indegree[i]);
            int check = indegree[node] + indegree[i] - 1;
            ans = max(ans, check);
            debug(ans);
        }
    }
    debug(ans);
    return ans;


}

void solve(){
    int n; cin >> n;
    vector<int>indegree(n + 1, 0);
    set<vector<int>>edges;
    for(int i = 1; i <= n - 1; ++i){
        int u, v;
        cin >> u >> v;
        edges.insert({u, v});
        indegree[u] += 1;
        indegree[v] += 1;
    }
    int maxin = *max_element(indegree.begin(), indegree.end());
    unordered_set<int>maxnodes;
    for(int i = 1; i <= n; ++i){
        if(indegree[i] == maxin){
            maxnodes.insert(i);
        }
        if(maxnodes.size() == 2) break;
    }
    debug(maxnodes);
    int ans = 0;
    for(auto &node: maxnodes){
        int check = calc(n, node, edges, indegree);
        debug(check);
        ans = max(ans, check);
    }
    debug("FINAL ANS: ", ans);
    cout << ans << endl;







}
int main() {
    FASTIO();
    int t; t = 1;
    cin >> t;
    while(t--){
        solve();
    }

}


Submission (verdict: Accepted):

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define FASTIO() \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL);
using namespace std;

//<------------------------------------------------------------------------------------------------------------------------------------------------------------------------------>
//                                                            DEBUG TEMPLATE
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}

#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

// ordered set
// find_by_order, order_of_key
// order_of_key (k) : Number of items strictly smaller than k.
// find_by_order(k) : K-th element in a set (counting from zero)
using namespace __gnu_pbds;
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update> ;
template<class T> using ordered_multiset = tree<T, null_type,less_equal<T>, rb_tree_tag,tree_order_statistics_node_update>;
template<class key, class value, class cmp = std::less<key>> using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
struct pair_hash {
    template <class T1, class T2>
    size_t operator()(const std::pair<T1, T2>& p) const {
        auto h1 = std::hash<T1>{}(p.first);
        auto h2 = std::hash<T2>{}(p.second);
        return h1 ^ (h2 << 1);
    }
};
class DSU{
    public:
    vector<int> Rank, parent;
    void make(int n) {
        Rank.resize(n+1,0);
        parent.resize(n+1);
        for (int i = 0; i <= n; i++) {
            parent[i] = i;
        }
    }
    int get(int node) {
        if (node == parent[node])
            return node;
        return parent[node] = get(parent[node]);
    }
    void unite(int u, int v) {
        int ulp_u = get(u);
        int ulp_v = get(v);
        if (ulp_u == ulp_v) return;
        if (Rank[ulp_u] < Rank[ulp_v]) {
            parent[ulp_u] = ulp_v;
        }
        else if (Rank[ulp_v] < Rank[ulp_u]) {
            parent[ulp_v] = ulp_u;
        }
        else {
            parent[ulp_v] = ulp_u;
            Rank[ulp_u]++;
        }
    }
};
//<----------------------------------------------------------------------------------------------------------------------------------------------------------------------------->

// lets say in degree of u and v is du and dv.
// if u and v are adjacent (one is the parent of other) then components = du + dv - 2;
// if u and v are not adjacent then components = du + dv - 1;
// Now its very obvious we greedily try to remove the max value of du.
// Now if we have more one max of du, then it is very obvious that we take any two max values that are not adjacent.
// But there maybe also a case where there all max values are adjacent to each other.
// what we do is simply take any two nodes u and v with max value(if they exist) and brute all node w with (u,w) and (v,w) and then finally
// check for (u,v). Now it is guarenteed that at least one  pair in (u,v), (v,w) and (u,w) they will not be adjacent
// since if they were it would have beem a cycle which is not possible in a tree

int calc(int n, int node, const vector<unordered_set<int>> &adj, const vector<int> &degree) {
    int best = 0;
    for (int i = 1; i <= n; i++) {
        if (i == node)
            continue;
        int candidate = degree[node] + degree[i] - (adj[node].count(i) ? 2 : 1);
        best = max(best, candidate);
    }
    return best;
}

void solve(){
    int n; cin >> n;
    vector<unordered_set<int>> adj(n + 1);
    vector<int> degree(n + 1, 0);
    for (int i = 1; i <= n - 1; i++){
        int u, v;
        cin >> u >> v;
        adj[u].insert(v); adj[v].insert(u);
        degree[u]++; degree[v]++;
    }
    int maxin = *max_element(degree.begin(), degree.end());
    vector<int>maxnodes;
    for(int i = 1; i <= n; ++i){
        if(degree[i] == maxin){
            maxnodes.push_back(i);
        }
        if(maxnodes.size() == 2) break;
    }
    int ans = 0;
    ans = max(ans, calc(n, maxnodes[0], adj, degree));
    if (maxnodes.size() == 2) {
        ans = max(ans, calc(n, maxnodes[1], adj, degree));
    }

    cout << ans << "\n";
}

int main() {
    FASTIO();
    int t; t = 1;
    cin >> t;
    while(t--){
        solve();
    }

}