結果
| 問題 | No.2072 Anatomy | 
| コンテスト | |
| ユーザー |  startcpp | 
| 提出日時 | 2022-09-17 05:25:05 | 
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 131 ms / 2,000 ms | 
| コード長 | 1,197 bytes | 
| コンパイル時間 | 703 ms | 
| コンパイル使用メモリ | 67,456 KB | 
| 実行使用メモリ | 7,552 KB | 
| 最終ジャッジ日時 | 2024-12-22 00:21:44 | 
| 合計ジャッジ時間 | 4,830 ms | 
| ジャッジサーバーID (参考情報) | judge5 / judge4 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 2 | 
| other | AC * 27 | 
ソースコード
//番号が大きい方からUnionFindで繋いでいく
//以下3つのルールによって得られる最終的な連結成分のスコア(= 操作回数)が答え。
//・単独頂点のスコアは0である
//・スコアa, bの連結成分を繋ぐとき、スコアmax(a, b) + 1の連結成分になる
//・スコアaの連結成分内に辺を追加するとき、スコアa + 1になる
#include <iostream>
#include <algorithm>
#define rep(i, n) for(i = 0; i < n; i++)
using namespace std;
struct UF {
	int par[200000];
	int score[200000];
	UF() {
		for (int i = 0; i < 200000; i++) {
			score[i] = 0;
			par[i] = i;
		}
	}
	int root(int x) {
		if (par[x] == x) return x;
		return par[x] = root(par[x]);
	}
	bool same(int x, int y) { return root(x) == root(y); }
	void add_edge(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			par[x] = y;
			score[y] = max(score[y], score[x]) + 1;
		}
		else {
			score[x]++;
		}
	}
};
int n, m;
int u[200000], v[200000];
UF uf;
int main() {
	int i;
	
	cin >> n >> m;
	rep(i, m) { cin >> u[i] >> v[i]; u[i]--; v[i]--; }
	for (i = m - 1; i >= 0; i--) {
		uf.add_edge(u[i], v[i]);
	}
	
	cout << uf.score[uf.root(0)] << endl;
	return 0;
}
            
            
            
        