最小全域木(ABC 065 D問題)
めっちゃ難しかった
問題
以下ネタバレ注意
問題
以下ネタバレ注意
- struct edge { int u, v, cost; };
- struct vertex { int p, x, y; };
- //比較関数
- bool comp(const edge& e1, const edge&e2) {
- return e1.cost < e2.cost;
- }
- bool compX(const vertex& v1, const vertex& v2) {
- return v1.x < v2.x;
- }
- bool compY(const vertex& v1, const vertex& v2) {
- return v1.y < v2.y;
- }
- edge es[2 * MAX];
- vertex ver[MAX];
- int N; int E;
- ll kruskal() {
- sort(es, es + E, comp);//costでソート
- init(N);
- ll res = 0;
- //コストが小さい辺から順に追加する
- REP(i, E) {
- edge e = es[i];
- //もし閉路ができなければその辺を追加する
- if (!same(e.u, e.v)) {
- unite(e.u, e.v);
- res += e.cost;
- }
- }
- return res;
- }
- int main() {
- cin >> N;
- REP(i, N) {
- int x, y;
- cin >> x >> y;
- ver[i] = {i, x,y };
- }
- E = 2*(N-1);
- //x座標でソート
- sort(ver, ver + N, compX);
- REP(i, N - 1) {
- //隣接した点の間にコスト|x1-x2|の辺を貼る
- es[i] = { ver[i].p,ver[i + 1].p,abs(ver[i].x - ver[i + 1].x) };
- }
- //y座標でソート
- sort(ver, ver + N, compY);
- REP(i, N - 1) {
- es[N - 1 + i] = { ver[i].p,ver[i + 1].p,abs(ver[i].y - ver[i + 1].y) };
- }
- ll ans=kruskal();
- cout << ans << endl;
- }