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;
}

 

posted @ 2015-05-31 19:22  moonbay  阅读(182)  评论(0编辑  收藏  举报