zoj 1406 Jungle Roads(Prim || Kruskal)

很简单的最小生成树类型,直接求连一起的最小路程。

 

Prim算法和DIJ很类似啊,就变了一步。。。

 

KRU让我纠结了好长时间,不过还好明白了,PRE数组中存的是与i同一集合的下标。。。

 

 //2015.9.16  复习Prim,被以前的代码丑哭了,更新一下

Prim

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <memory>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;

class Node {
public :
    Node *next;
    int to;
    int val;
    Node(int to, int val, Node* next) : to(to), val(val), next(next) {}
};
void add(vector<Node*> &road, int from, int to, int val) {
    Node *t = new Node(to, val, road[from]);
    road[from] = t;
}
void input(int n, vector<Node*> &road) {
    getchar();
    char from, to;
    int num, len;
    for (int i = 1; i < n; i++) {
        scanf("%c %d", &from, &num);
        int a = from - 'A';
        while (num--) {
            scanf(" %c %d", &to, &len);
            int b = to - 'A';
            add(road, a, b, len);
            add(road, b, a, len);
        }
        getchar();
    }
}
void prim(int n, vector<Node*> &road) {
    vector<bool> visit(n, false);
    vector<int> dist(n, INT_MAX);
    int now = 0, sum = 0;
    dist[0] = 0;
    visit[0] = true;
    for (int i = 1; i < n; i++) {
        for (auto head = road[now]; head != NULL; head = head->next) {
            int to = head->to, len = head->val;
            if (!visit[to] && dist[to] > len) {
                dist[to] = len;
            }
        }
        int min_len = INT_MAX;
        for (int k = 0; k < n; k++) {
            if (!visit[k] && dist[k] < min_len) {
                min_len = dist[now = k];
            }
        }
        sum += min_len;
        visit[now] = true;
    }
    printf("%d\n", sum);
}
int main(void) {
    int n;
    while (scanf("%d",&n) != EOF && n) {
        vector<Node*> road(n, NULL);
        input(n, road);
        prim(n, road);
    }
    return 0;
}


 

Kruskal

 //2015.9.16 更新

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <memory>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;

class Edge {
public :
    int u, v, len;
    Edge(int u, int v, int len) : u(u), v(v), len(len) {}
    bool operator<(const Edge &a) const {
        return this->len < a.len;
    }
};
void input(int n, vector<Edge> &edge) {
    getchar();
    char from, to;
    int num, len;
    for (int i = 1; i < n; i++) {
        scanf("%c %d", &from, &num);
        int a = from - 'A';
        while (num--) {
            scanf(" %c %d", &to, &len);
            int b = to - 'A';
            edge.push_back(Edge(a, b, len));
        }
        getchar();
    }
}
int findPre(int x, vector<int> &pre) {
    while (x != pre[x])
        x = pre[x];
    return x;
}
int kruskal(int n, vector<Edge> &edge) {
    sort(edge.begin(), edge.end());
    vector<int> pre(n, 0);
    int sum = 0;
    for (int i = 0; i < n; i++) {
        pre[i] = i;
    }
    for (auto &e : edge) {
        int a = findPre(e.u, pre);
        int b = findPre(e.v, pre);
        if (a != b) {
            pre[b] = a;
            sum += e.len;
        }
    }
    return sum;
}
int main(void) {
    int n;
    while (scanf("%d",&n) != EOF && n) {
        vector<Edge> edge;
        input(n, edge);
        cout << kruskal(n, edge) << endl;
    }
    return 0;
}


你可能感兴趣的:(zoj 1406 Jungle Roads(Prim || Kruskal))