并查集求调
查看原帖
并查集求调
1033990
lw393楼主2024/12/29 20:32
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cassert>
#include<map>
using namespace std;

struct UnionFind
{
	private:
	int n;
	vector<int> par,siz;

	public:
	UnionFind(int n) :n(n),par(n,-1),siz(n,1) {}

	int root(int u)
	{
		assert(0 <= u && u < n);
		return (par[u] < 0 ? u:par[u] = root(par[u]));
	}

	bool same(int u,int v)
	{
		assert(0 <= u && u < n && 0 <= v && v < n);
		return root(u) == root(v);
	}

	bool merge(int u,int v)
	{
		assert(0 <= u && u < n && 0 <= v && v < n);
		u = root(u),v = root(v);
		if(u == v) return false;

		if(siz[u] < siz[v]) swap(u,v);

		siz[u] += siz[v];
		par[v] = u;

		return true;
	}

	int size(int u)
	{
		assert(0 <= u && u < n);
		return siz[root(u)];
	}

	vector<vector<int>> components()
	{
		vector<vector<int>> ret(n);
		for(int u = 0;u < n;u++) ret[root(u)].push_back(u);

		ret.erase(remove_if(ret.begin(),ret.end(),[](vector<int> v) { return v.empty();}),ret.end());

		return ret;
	}
};

const int N = 3e5 + 5;

int u[N], v[N];

void solve(){
    int n, m;
    cin >> n >> m;
    UnionFind dsu(n + 1);
    for(int i = 1; i <= m; i++){
        cin >> u[i] >> v[i];
        if(dsu.same(u[i], v[i])) {
            cout << "No\n";
            return;
        }
        dsu.merge(u[i], v[i]);
    }
    cout << "Yes\n";
    for(int i = 1; i <= m; i++) cout << u[i] << ' ' << v[i] << '\n';
    for(int i = 1; i <= n; i++){
        if(dsu.same(i, 1)) continue;
        else cout << 1 << ' ' << i << '\n', dsu.merge(i, 1);
    }
}

int main(){
    int t = 1;
    //cin >> t;
    while(t--){
        solve();
    }
    return 0;
}
2024/12/29 20:32
加载中...