//prim算法
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<cstdlib> #include<algorithm> #include<string> #include<stack> #include<queue> #include<map> #define MAX 510 const int INF=1000000000; using namespace std; //顶点到集合s的最短距离 int d[MAX],G[MAX][MAX]; int n,m; bool isVisit[MAX]={false}; //返回最小生成树的边权之和 int prim(){ fill(d,d+MAX,INF); d[0]=0; int ans=0; for(int i=0;i<n;i++){ int u=-1,MIN=INF; for(int j=0;j<n;j++){ if(isVisit[j]==false&&d[j]<MIN){ u=j; MIN=d[j]; } } if(u==-1) return -1; isVisit[u]=true; ans+=d[u]; for(int v=0;v<n;v++){ if(isVisit[v]==false&&G[u][v]!=INF&&G[u][v]<d[v]) d[v]=G[u][v]; } } return ans; } int main(){ int u,v,w; //顶点个数,边数 scanf("%d%d",&n,&m); //初始化图 fill(G[0],G[0]+MAX*MAX,INF); for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&w); G[u][v]=G[v][u]=w; } int ans=prim(); printf("%d\n",ans); return 0; }

  类似Dijkstra算法,但是此时d[]表示顶点Vi与集合S的最短距离

kruskal算法:

运用并查集,判断两个点是否在一个及集合中,,即测试两个端点是否在不同连通块中

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<map>
const int MAX=110;
const int MAXE=10010;
const int INF=1000000000;
using namespace std;
//顶点到集合s的最短距离
int d[MAX],father[MAX];
int n,m;
bool isVisit[MAX]={false};
struct edge{
    int node1,node2;
    int weight;
}E[MAXE];
bool cmp(edge e1,edge e2){
    return e1.weight<e2.weight;
}
int findFather(int x){
    int a=x;
    while(x!=father[x]){
        x=father[x];
    }
    while(a!=father[a]){
        int temp=a;
        a=father[a];
        father[temp]=x;
    }
    return x;
}
int kruskal(){
    int ans=0,num_edge=0;
    for(int i=0;i<n;i++)
        father[i]=i;
    sort(E,E+m,cmp);
    for(int i=0;i<m;i++){
        int f1=findFather(E[i].node1);
        int f2=findFather(E[i].node2);
        if(f1!=f2){
            father[f1]=f2;
            ans+=E[i].weight;
            num_edge++;
            //边数等于顶点数-1结束
            if(num_edge==n-1) break;
        }
    }
    if(num_edge!=n-1) return -1;
    else return ans;
}

int main(){
    //顶点个数,边数
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&E[i].node1,&E[i].node2,&E[i].weight);
    }
    int ans=kruskal();
    printf("%d\n",ans);
    return 0;
}

 

posted on 2018-04-09 16:39  Sunshine&暖阳  阅读(94)  评论(0编辑  收藏  举报