最小生成树 PRIM KRUSKAL

来源:互联网 发布:阿里云客服网址 编辑:程序博客网 时间:2024/05/21 04:19

SDUT 2144
与此题为例讲一下prim算法
简要概括最短路和最小生成树的区别
一句话概括:最小生成树是计算从一节点到另一节点的最小边集;最短路是带权路径,计算权值最小。也就是说,最小生成树要经过每一个点,而最短路只需要能达到某两点,路径权值最小即可!(这句话摘自其他博客)
prim的算法内容和最短路的DJ算法差不多

#include <bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;int tu[105][105];int vis[105];int mincost[105];//标记最小权值int n;int prim(){    memset(vis,0,sizeof(vis));    for(int i=1; i<=n; i++)//初始化从一开始到每个点的距离所以小于等于n    {        mincost[i]=tu[1][i];    }    vis[1]=1;    int ans=0;    for(int i=2; i<=n; i++)//找剩余的n-1个点    {        int pos=i;        int M=INF;        for(int j=1; j<=n; j++)        {            if(!vis[j]&&mincost[j]<M)            {                M=mincost[j];                pos=j;            }        }        ans+=M;        vis[pos]=1;        for(int j=1; j<=n; j++)//松弛//更新从当前点到每个点的最短距离        {            if(!vis[j]&&mincost[j]>tu[pos][j])            {                mincost[j]=tu[pos][j];            }        }    }    return ans;}int main(){    int m,j,k,l;    while(~scanf("%d %d",&n,&m))//n为点数,m为边数    {        for(int i=1; i<=n; i++)//图的预处理            for(int u=1; u<=n; u++)                i==u?tu[i][u]=1:tu[i][u]=INF;        for(int i=0; i<m; i++)//边数        {            scanf("%d %d %d",&j,&k,&l);//无向图            if(tu[j][k]>l)            {                tu[j][k]=l;                tu[k][j]=l;            }        }        int x=prim();        printf("%d\n",x);    }}

SDUT 2144

依旧是这道题目讲一下kruskal

kruskal可以运用了并查集,,不懂得去学吧(但是如果你都开始做这类题了,并查集没理由不会啊)

#include <bits/stdc++.h>using namespace std;struct node{    int u,v,w;}tu[10005];int p[1004],n,m;bool cmp(node a,node b){    return a.w<b.w;}int fing(int x)//找大哥{    return p[x]==x?x:p[x]=fing(p[x]);}void kruskal(){    int ans=0;    int cnt=0;    for(int i=1;i<=n;i++)//初始化并茶几数组,以点为下标所以为点数n        p[i]=i;    for(int i=1;i<=m;i++)//按边生成    {        int x=fing(tu[i].u),y=fing(tu[i].v);        if(x!=y)        {            p[x]=y;            ans+=tu[i].w;            cnt++;            if(cnt==n)//所有点都走完了退出                break;        }    }    printf("%d\n",ans);}int main(){    while(~scanf("%d %d",&n,&m))    {        for(int i=1; i<=m; i++)//俺边数输入        {            scanf("%d %d %d",&tu[i].u,&tu[i].v,&tu[i].w);        }        sort(tu+1,tu+m+1,cmp);//kruskal按照边权的大小来查找最小边权        kruskal();    }}
原创粉丝点击