最小生成树模板

元气小坏坏 提交于 2020-02-13 13:55:23

Prim算法,O(V^2),适用于稠密图。

 1 const int N=1000;
 2 const int INF=0x3f3f3f3f;
 3 int a[N][N],p[N],low[N];///邻接矩阵 
 4 int prim(int n)
 5 {
 6     int i,j,ans=0,poi;
 7     memset(p,0,sizeof(p));
 8     p[1]=1;
 9     for(i=1;i<=n;i++)
10         low[i]=a[1][i];
11     for(i=1;i<n;i++)           ////n-1次操作
12     {
13         int mi=INF;
14         for(j=1;j<=n;j++)
15         {
16             if(!p[j]&&mi>low[j])
17             {
18                 mi=low[j];
19                 poi=j;
20             }
21         }
22         p[poi]=1;
23         ans+=mi;
24         for(j=1;j<=n;j++)
25             if(!p[j])
26                 low[j]=min(low[j],a[poi][j]);
27     }
28     return ans;
29 }
Prim

Kruskal,O(ElogE)。将边按权值从小到大排序,枚举每一条边,若该边的两端不在同一集合中,合并集合。直到找到n-1条边(n为点数)。判断是否在一个集合也可以用并查集做。

 1 ////O(ElogE)  适用于稀疏图
 2 const int N=1000;
 3 const int M=N*N;
 4 int p[N];
 5 struct edge
 6 {
 7     int u,v,w;
 8 }e[M];
 9 int cmp(edge a,edge b)
10 {
11     return a.w<b.w;
12 }
13 int kruskal(int n,int m)
14 {
15     sort(e+1,e+m+1,cmp);           ////下标从1开始
16     int i,j,k,ans=0,num=0;
17     for(i=1;i<=n;i++)
18         p[i]=i;
19     for(i=1;i<=m&&num<=n-1;i++)
20     {
21         ////判断两端点所在集合
22         for(j=e[i].u;p[j]!=j;j=p[j])
23             p[j]=p[p[j]];
24         for(k=e[i].v;p[k]!=k;k=p[k])
25             p[k]=p[p[k]];
26         if(j!=k)
27         {
28             p[j]=k;
29             num++;
30             ans+=e[i].w;
31         }
32     }
33     return ans;
34 }
Kruskal

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!