hdu 5253 最小生成树

赤裸裸最小生成树,没啥说的,我用kruskal过的

/*

 * Author    : ben

 */

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <queue>

#include <set>

#include <map>

#include <stack>

#include <string>

#include <vector>

#include <deque>

#include <list>

#include <functional>

#include <numeric>

#include <cctype>

using namespace std;

/*

 * 输入非负整数

 * 支持short、int、long、long long等类型(修改typec即可)。

 * 用法typec a = get_int();返回-1表示输入结束

 */

typedef int typec;

typec get_int() {

    typec res = 0, ch;

    while (!((ch = getchar()) >= '0' && ch <= '9')) {

        if (ch == EOF)

            return -1;

    }

    res = ch - '0';

    while ((ch = getchar()) >= '0' && ch <= '9')

        res = res * 10 + (ch - '0');

    return res;

}

//输入整数(包括负整数,故不能通过返回值判断是否输入到EOF,本函数当输入到EOF时,返回-1),用法int a = get_int2();

int get_int2() {

    int res = 0, ch, flag = 0;

    while (!((ch = getchar()) >= '0' && ch <= '9')) {

        if (ch == '-')

            flag = 1;

        if (ch == EOF)

            return -1;

    }

    res = ch - '0';

    while ((ch = getchar()) >= '0' && ch <= '9')

        res = res * 10 + (ch - '0');

    if (flag == 1)

        res = -res;

    return res;

}





const int MAXM = 2000000;

const int MAXN = 3000000;

typedef struct {

    int s, e;

    typec len;

} MyEdge;

int myset[MAXM], myheight[MAXM];

MyEdge edges[MAXN];

int N, M;

inline bool operator<(const MyEdge &e1, const MyEdge &e2) {

    return e1.len < e2.len;

}

void initset() {

    for (int i = 0; i <= M; i++) {

        myset[i] = i;

        myheight[i] = 1;

    }

}

int myfind(int x) {

    while (myset[x] != x) {

        x = myset[x];

    }

    return x;

}

void mymerge(int a, int b) {

    if (myheight[a] == myheight[b]) {

        myheight[a]++;

        myset[b] = a;

    } else if (myheight[a] < myheight[b]) {

        myset[a] = b;

    } else {

        myset[b] = a;

    }

}



int kruskal() {

    int ret = 0, x, y, z;

    sort(edges, edges + N);

    initset();

    for (int i = 0; i < N; i++) {

        x = edges[i].s;

        y = edges[i].e;

        z = edges[i].len;

        if (myfind(x) == myfind(y)) {

            continue;

        }

        mymerge(myfind(x), myfind(y));

        ret += z;

    }

    return ret;

}



int graph[1010][1010];



void buildgraph() {

    int nn = get_int(), mm = get_int();

    for (int i = 0; i < nn; i++) {

        for (int j = 0; j < mm; j++) {

            graph[i][j] = get_int();

        }

    }

    M = nn * mm;

    N = 0;

    for (int i = 0; i < nn - 1; i++) {

        for (int j = 0; j < mm - 1; j++) {

            edges[N].s = i * mm + j;

            edges[N].e = i * mm + j + 1;

            edges[N].len = abs(graph[i][j] - graph[i][j + 1]);

            N++;

            edges[N].s = i * mm + j;

            edges[N].e = i * mm + mm + j;

            edges[N].len = abs(graph[i][j] - graph[i + 1][j]);

            N++;

        }

        edges[N].s = i * mm + mm - 1;

        edges[N].e = i * mm + mm + mm - 1;

        edges[N].len = abs(graph[i][mm - 1] - graph[i + 1][mm - 1]);

        N++;

    }

    for (int j = 0; j < mm - 1; j++) {

        edges[N].s = (nn - 1) * mm + j;

        edges[N].e = (nn - 1) * mm + j + 1;

        edges[N].len = abs(graph[nn - 1][j] - graph[nn - 1][j + 1]);

        N++;

    }

//    printf("N = %d, M = %d\n", N, M);

}



int main() {

//    freopen("test.in.txt", "r", stdin);

    int T = get_int();

    for (int t = 1; t <= T; t++) {

        buildgraph();

        printf("Case #%d:\n%d\n", t, kruskal());

    }

    return 0;

}

 

你可能感兴趣的:(最小生成树)