Catshock

Catshock

二分图
奇偶染色,删除叶子,直到只剩点n即可

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    int n; cin >> n;
    vector<vector<int>> g(n + 1);
    vector<int> deg(n + 1, 0);
    for(int i = 1; i < n; i ++) {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
        deg[u] ++; deg[v] ++;
    }
    //染色
    vector<int> col(n + 1, -1); col[1] = 1;
    queue<int> q; q.push(1);
    while(!q.empty()) {
        int u = q.front(); q.pop();
        for(int v : g[u]) {
            if(col[v] != -1) continue;
            col[v] = col[u] ^ 1;
            q.push(v);
        }
    }

    queue<int> q0, q1;
    for(int i = 1; i < n; i ++) {
        if(deg[i] == 1) {
            if(col[i] == 1) q1.push(i);
            else q0.push(i);
        }
    }
    //操作,做多摧毁n - 1次
    vector<int> opra;
    int cnt = 0;
    int cur = 1;
    while(cnt < n - 1) {
        if(cur == 0) {
            if(q1.empty()) {opra.push_back(0); cur ^= 1; continue;}
            int u = q1.front(); q1.pop();
            opra.push_back(u); opra.push_back(0); cur ^= 1;
            for(int v : g[u]) {
                deg[v] --;
                if(deg[v] == 1 && v != n) q0.push(v);
            }
            cnt ++; 
        }
        else {
            if(q0.empty()) {opra.push_back(0); cur ^= 1; continue;}
            int u = q0.front(); q0.pop();
            opra.push_back(u);
            for(int v : g[u]) {
                deg[v] --;
                if(deg[v] == 1 && v != n) q1.push(v);
            }
            cnt ++; opra.push_back(0); cur ^= 1;
        }
    }
    cout << opra.size() << "\n";
    for(int i = 0; i < opra.size(); i ++) {
        if(opra[i] == 0) cout << "1\n";
        else cout << "2 " << opra[i] << "\n";
    }
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int _ = 1; cin >> _;
    while(_--) solve();
    return 0;
}
posted @ 2026-11-03 22:16  thenrify  阅读(3)  评论(0)    收藏  举报