生成树

来源:互联网 发布:www.4399js.com 编辑:程序博客网 时间:2024/06/07 22:15

Prim算法

const int inf = 0x3f3f3f;const int maxn = (300 + 10);bool vis[maxn];int lowc[maxn];int cost[maxn][maxn];int Prim(int n){    int ans = 0;    memset(vis,false,sizeof(vis));    vis[0] = true;    for(int i = 1;i < n;i++)    lowc[i] = cost[0][i];    for(int i = 1;i < n;i ++){        int minc = inf;        int p = -1;        for (int j = 0; j < n; j++) {            if (!vis[j] && minc > lowc[j]) {                minc = lowc[j];                p = j;            }        }        if (minc == inf)    return -1;        ans += minc;        vis[p] = true;        for (int j = 0; j < n; j++) {            if (!vis[j] && lowc[j] > cost[p][j]) {                lowc[j] = cost[p][j];            }        }    }    return ans;}

Kruskal算法

const int inf = 1000000000;const int maxn = (1000 + 10);struct Edge{    int u,v;    int w;    Edge(){}    Edge(int _u,int _v,int _w){        u = _u;        v = _v;        w = _w;    }}edge[maxn * maxn];bool cmp(Edge a,Edge b){    return a.w < b.w;}int Map[maxn];int t = 0;int find(int x){    if(Map[x] == -1)    return x;    return Map[x] = find(Map[x]);}int Kruskal(int n){    memset(Map,-1,sizeof(Map));    sort(edge,edge + t,cmp);    int cnt = 0;    int ans = 0;    for(int i = 0;i < t;i ++){        int u = edge[i].u;        int v = edge[i].v;        int w = edge[i].w;        u = find(u);        v = find(v);        if(u != v){            ans += w;            Map[u] = v;            cnt ++;        }        if(cnt == n - 1)    break;    }    if(cnt < n - 1) return -1;    return ans;}

次小生成树Prim

求出来的依旧是最小的,再根据Max[][]数组求次小生成树

bool vis[maxn];int lowc[maxn];int pre[maxn];int Max[maxn][maxn];bool used[maxn][maxn];int cost[maxn][maxn];int Prim(int n) {    int ans = 0;    memset(vis,false,sizeof(vis));    memset(Max,0,sizeof(Max));    memset(used,false,sizeof(used));    vis[0] = true;    pre[0] = -1;    for(int i = 1; i < n; i++) {        lowc[i] = cost[0][i];        pre[i] = 0;    }    lowc[0] = 0;    for(int i = 1; i < n; i ++) {        int minc = inf;        int p = -1;        for (int j = 0; j < n; j++) {            if (!vis[j] && minc > lowc[j]) {                minc = lowc[j];                p = j;            }        }        if (minc == inf)    return -1;        ans += minc;        vis[p] = true;        used[p][pre[p]] = used[pre[p]][p] = true;        for (int j = 0; j < n; j++) {            if(vis[j] && j != p) Max[j][p] = Max[p][j] = max(Max[j][pre[p]],lowc[p]);            if (!vis[j] && lowc[j] > cost[p][j]) {                lowc[j] = cost[p][j];                pre[j] = p;            }        }    }    return ans;}

最小树形图

struct Edge{    int u,v;    int cost;}edge[maxm];int pre[maxn],id[maxn],visit[maxn],in[maxn];int zhuliu(int root,int n,int m,Edge edge[]){    int res = 0,u, v;    while(1){        for(int i = 0;i < n;i ++)   in[i] = inf;        for(int i = 0;i < m;i ++){            if(edge[i].u != edge[i].v && edge[i].cost < in[edge[i].v]){                pre[edge[i].v] = edge[i].u;                in[edge[i].v] = edge[i].cost;            }        }        for(int i = 0;i < n; i++){            if(i != root && in[i] == inf)   return -1;        }        int tn = 0;        memset(id,-1,sizeof(id));        memset(visit,-1,sizeof(visit));        for(int i = 0;i < n;i ++){            res += in[i];            v = i;            while(visit[v] != i && id[v] == -1 && v != root){                visit[v] = i;                v = pre[v];            }            if(v != root && id[v] == -1){                for (int u = pre[v]; u != v; u = pre[u])                    id[u] = tn;                id[v] = tn++;            }        }        if(tn == 0) break;        for(int i = 0;i < m;){            v = edge[i].v;            edge[i].u = id[edge[i].u];            edge[i].v = id[edge[i].v];            if(edge[i].u != edge[i].v)  edge[i ++].cost -= in[v];            else        swap(edge[i],edge[--m]);        }        n = tn;        root = id[root];    }    return res;}
0 0