码迷,mamicode.com
首页 > 其他好文 > 详细

最小生成树模板

时间:2015-08-16 10:36:24      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

1.prim

prim算法的效率取决于节点数,适用于稠密图。

技术分享
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

#define INF 0x7fffffff
#define MAXN 128
bool vis[MAXN];
int lowc[MAXN];

int prim(int cost[][MAXN],int n){//标号从0开始
    int ans=0,i,j,minc,p;
    memset(vis,false,sizeof(vis));
    vis[0]=true;
    for(i=1;i<n;++i)lowc[i]=cost[0][i];
    for(i=1;i<n;++i){
        minc=INF;
        p=-1;
        for(j=0;j<n;++j)
            if(!vis[j]&&lowc[j]<minc){
                minc=lowc[j];
                p=j;
            }
        if(minc==INF)return -1;//原图不连通
        ans+=minc;
        vis[p]=true;
        for(j=0;j<n;++j)
            if(!vis[j]&&cost[p][j]<lowc[j])
                lowc[j]=cost[p][j];
    }
    return ans;
}

int main(){
    int n,m,a,b,w,i;
    int cost[MAXN][MAXN];
    while(~scanf("%d",&n)&&n){
        m=n*(n-1)/2;//m边条数
        for(i=0;i<m;++i){
            scanf("%d%d%d",&a,&b,&w);
            --a;--b;
            cost[a][b]=cost[b][a]=w;
        }
        printf("%d\n",prim(cost,n));
    }
    return 0;
}
View Code

 

2.kruskal

kruskal算法的效率取决于边数,适用于稀疏图。

技术分享
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 110//最大点数
#define MAXM 10000//最大边数
int F[MAXN];//并查集使用

struct Edge{
    int u,v,w;
}edge[MAXM];//存储边的信息,包括起点/终点/权值
int tol;//边数,加边前赋值为0

void addedge(int u,int v,int w){
    edge[tol].u=u;
    edge[tol].v=v;
    edge[tol++].w=w;
}

//排序函数,将边按照权值从小到大排序
bool cmp(Edge a,Edge b){
    return a.w<b.w;
}

int find(int x){
    if(F[x]==-1)return x;
    return F[x]=find(F[x]);
}

//传入点数,返回最小生成树的权值,如果不连通返回-1
int kruskal(int n){
    memset(F,-1,sizeof(F));
    sort(edge,edge+tol,cmp);
    int cnt=0;//计算加入的边数
    int ans=0,i,u,v,w,t1,t2;
    for(i=0;i<tol;++i){
        u=edge[i].u;
        v=edge[i].v;
        w=edge[i].w;
        t1=find(u);
        t2=find(v);
        if(t1!=t2){
            ans+=w;
            F[t1]=t2;
            ++cnt;
        }
        if(cnt==n-1)break;
    }
    if(cnt<n-1)return -1;//不连通
    return ans;
}

int main(){
    int n,m,a,b,w,i;
    while(~scanf("%d",&n)&&n){
        m=n*(n-1)/2;//m边条数
        tol=0;
        for(i=0;i<m;++i){
            scanf("%d%d%d",&a,&b,&w);
            addedge(a,b,w);
        }
        printf("%d\n",kruskal(n));
    }
    return 0;
}
View Code

 

最小生成树模板

标签:

原文地址:http://www.cnblogs.com/bofengyu/p/4733681.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!