公式

D - Unicyclic Components 解説 by m_99


無向グラフの連結性を簡潔に管理する方法として、UnionFind(DSU)というデータ構造があります。本解説ではAtCoder Libraryのdsuを用いた解法を示します。

本問を解く上で、与えられたグラフにおいて各頂点・各辺がどの連結成分に含まれているかを把握する必要があります。AtCoder Libraryのdsuでは、以下のようにして頂点 xx が含まれる連結成分を代表する頂点の番号を得られます。

Copy
  1. //atcoder::dsu Dを使い、lにxが含まれる連結成分を代表する頂点の番号を代入する
  2. l = D.leader(x);
//atcoder::dsu Dを使い、lにxが含まれる連結成分を代表する頂点の番号を代入する
l = D.leader(x);

これを用いて任意の連結成分において頂点数と辺数が等しいかどうかを判定すれば良いです。

実装例(C++)

Copy
  1. #include <bits/stdc++.h>
  2. #include <atcoder/dsu>
  3. using namespace std;
  4. using namespace atcoder;
  5. int main() {
  6. int N,M;
  7. cin>>N>>M;
  8. vector<int> u(M),v(M);
  9. for(int i=0;i<M;i++){
  10. cin>>u[i]>>v[i];
  11. u[i]--,v[i]--;
  12. }
  13. dsu D(N);
  14. for(int i=0;i<M;i++){
  15. D.merge(u[i],v[i]);
  16. }
  17. vector<int> vs(N),es(N);
  18. for(int i=0;i<N;i++){
  19. vs[D.leader(i)]++;
  20. }
  21. for(int i=0;i<M;i++){
  22. es[D.leader(u[i])]++;
  23. }
  24. if(vs==es)cout<<"Yes"<<endl;
  25. else cout<<"No"<<endl;
  26. return 0;
  27. }
#include <bits/stdc++.h>
#include <atcoder/dsu>
using namespace std;
using namespace atcoder;

int main() {
    
	int N,M;
	cin>>N>>M;
	vector<int> u(M),v(M);
	for(int i=0;i<M;i++){
		cin>>u[i]>>v[i];
		u[i]--,v[i]--;
	}
	
	dsu D(N);
	for(int i=0;i<M;i++){
		D.merge(u[i],v[i]);
	}
	
	vector<int> vs(N),es(N);
	for(int i=0;i<N;i++){
		vs[D.leader(i)]++;
	}
	
	for(int i=0;i<M;i++){
		es[D.leader(u[i])]++;
	}
	
	if(vs==es)cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	
	return 0;
}

投稿日時:
最終更新:



2025-04-09 (水)
23:03:21 +00:00