Tree Orientation (Easy Version)

Tree Orientation (Easy Version)

偏序关系,哈斯图
利用可达性建树,无法通过中间节点而可达的点建边,最后检查树是否完整

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

void solve() {
    int n; cin >> n;
    vector<string> g(n);
    for(int i = 0; i < n; i ++) cin >> g[i];
    
    //自反性
    for(int i = 0; i < n; i ++) 
        if(g[i][i] == '0') {cout << "NO\n"; return;}
    //反对称性
    for(int i = 0; i < n; i ++) {
        for(int j = i + 1; j < n; j ++) 
            if(i != j && g[i][j] == '1' && g[j][i] == '1') {cout << "NO\n"; return;}
    }
    //传递性
    for(int i = 0; i < n; i ++) {
        for(int j = 0; j < n; j ++) {
            if(i == j) continue;
            if(g[i][j] == '1') {
                for(int k = 0; k < n; k ++) 
                    if(g[j][k] == '1' && g[i][k] != '1') {cout << "NO\n"; return;}
            }
        }
    }
    
    vector<pair<int, int>> edge;//找边
    for(int i = 0; i < n; i ++) {
        for(int j = 0; j < n; j ++) {
            if(i == j) continue;
            if(g[i][j] == '1') {
                bool covered = false;
                for(int k = 0; k < n; k ++) {
                    if(k == i || k == j) continue;
                    if(g[i][k] == '1' && g[k][j] == '1') {covered = true; break;}
                }
                if(!covered) edge.push_back({i+1, j+1});
            }
        }
    }

    if(edge.size() != n - 1) {cout << "NO\n"; return;}

    vector<vector<int>> adj(n + 1);
    for(auto [u, v] : edge) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    queue<int> q; q.push(1);
    vector<int> vis(n + 1, 0); vis[1] = 1;
    int cnt = 0;
    while(!q.empty()) {
        int u = q.front(); q.pop();
        cnt ++;
        for(int v : adj[u]) {
            if(!vis[v]) {
                vis[v] = 1;
                q.push(v);
            }
        }
    }
    if(cnt != n) {cout << "NO\n"; return;}
    
    cout << "YES\n";
    for(auto [u, v] : edge) cout << u << " " << v << "\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:12  thenrify  阅读(2)  评论(0)    收藏  举报