POJ-1251(最小生成树)

来源:互联网 发布:多维元素片 知乎 编辑:程序博客网 时间:2024/05/29 11:39

最基本的最小生成树

Prim算法:


#include <vector>#include <utility>#include <cstdio>using namespace std;#define INF 1000typedef pair<int,int> Edge;int N;vector<Edge> vertex[26];bool inq[26];int  dis[26];int prim(){    int total = 0;    const vector<Edge>& v = vertex[0];    for(int i = 0; i < N; ++i) dis[i] = INF;    for(int i = 0, n = v.size(); i < n; ++i){        dis[v[i].first] = v[i].second;    }    inq[0] = true;    dis[0] = 0;        for(int i = 1; i < N; ++i){        int x = -1, d = INF;        for(int j = 0; j < N; ++j){            if(!inq[j] && dis[j] < d){                x = j;                d = dis[j];            }        }        inq[x] = true;        total += dis[x];        const vector<Edge>& v = vertex[x];        for(int j = 0, n = v.size(); j < n; ++j){            if(!inq[v[j].first] && dis[v[j].first] > v[j].second)                dis[v[j].first] = v[j].second;        }    }    return total;}int main(){    char from, to;    int  m, cost;    while(scanf("%d", &N), N){        for(int i = 0; i < N; ++i){            inq[i] = false;            vertex[i].clear();        }        for(int i = 1; i < N; ++i){            scanf(" %c %d", &from, &m);            for(int j = 0; j < m; ++j){                scanf(" %c %d", &to, &cost);                vertex[from - 'A'].push_back(Edge(to - 'A', cost));                vertex[to - 'A'].push_back(Edge(from - 'A', cost));            }        }        printf("%d\n", prim());    }    return 0;}

Kruskal算法:


#include <vector>#include <cstdio>#include <algorithm>using namespace std;struct Edge{    int u, v, c;    Edge(int uu, int vv, int cc):u(uu), v(vv), c(cc){}    friend bool operator < (const Edge& a, const Edge& b){        return a.c < b.c;    }};int N;vector<Edge> edges;bool inputGraph(){    scanf("%d", &N);    if(N == 0) return false;    edges.clear();    char from, to;    int  m, cost;    for(int i = 1; i < N; ++i){        scanf(" %c %d", &from, &m);        for(int j = 0; j < m; ++j){            scanf(" %c %d", &to, &cost);            edges.push_back(Edge(from - 'A', to - 'A', cost));        }    }    return true;}int  ancestor[26];int Find(int x){    return ancestor[x] == x ? x : ancestor[x] = Find(ancestor[x]);}int kruskal(){//initialize    for(int i = 0; i < 26; ++i) ancestor[i] = i;//sort up edges    sort(edges.begin(), edges.end());//kruskal    int totalCost = 0, cnt = 1, i = 0, n = edges.size();    for(; cnt < N && i < n; ++i){        int u = edges[i].u, v = edges[i].v;        int fu = Find(u), fv = Find(v);        if(fu != fv){            ancestor[fu] = fv;            totalCost += edges[i].c;            ++cnt;        }    }    return totalCost;}int main(){    while(inputGraph()) printf("%d\n", kruskal());    return 0;}
实际上,由于本题中E <= 76,V <= 26,所以Kruskal算法的O(ElogE)要优于Prim算法的O(N*N)



0 0