1. 程式人生 > 其它 >連線格點【最小生成樹】

連線格點【最小生成樹】

技術標籤:最小生成樹

連線格點

題目

思路:把二維座標對映到一維的點上,就是一個最小生成樹問題,再把點連線,先連上下再連左右可以省去排序過程

具體程式碼如下

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010, M = N*N, K = 2*M;

struct Node{
    int a, b, w;
}node[K];

int n, m, k;
int idx[N][N];
int p[M];

int find(int x){
    if(p[
x] != x) p[x] = find(p[x]); return p[x]; } void get_edges() { int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}, dw[4] = {1, 2, 1, 2}; for (int z = 0; z < 2; z ++ ) for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) for (int u = 0; u <
4; u ++ ) if (u % 2 == z) { int x = i + dx[u], y = j + dy[u], w = dw[u]; if (x && x <= n && y && y <= m) { int a = idx[i][j], b =
idx[x][y]; if (a < b) node[k ++ ] = {a, b, w}; } } } int main(){ cin >> n >> m; for(int i=1; i<=n*m; ++i) p[i] = i; for(int i=1, t=1; i<=n; ++i) for(int j=1; j<=m; ++j, ++t) idx[i][j] = t; int x1, x2, y1, y2; while(cin >> x1 >> y1 >> x2 >> y2){ int a = idx[x1][y1], b = idx[x2][y2]; p[find(a)] = find(b); } get_edges(); int res = 0; for(int i=0; i<k; ++i){ int a = node[i].a, b = node[i].b, w = node[i].w; a = find(a), b = find(b); if(a != b){ p[a] = b; res += w; } } cout << res << endl; return 0; }