今天是最小生成树的prim的算法,因为本人水平有限所以堆优化都不是很会啊,但邻接表好像出了点小差错所以上邻接矩阵比较好一点,尽管比Kruskal慢了很多很多但这种贪心思想还是要学习的。从第一条边开始取然后进行取n-1条边取完即可于是每取一条边就进行来对其他的边进行更新这样找最小值。下面代码。
#include<iostream> #include<cmath> #include<cstring> #include<string> #include<ctime> #include<cstdio> #include<algorithm> #include<map> #include<vector> #include<stack> #include<queue> #include<iomanip> using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m; int a[5009][5009]; int ans=0; int dis[5008]; int vis[5008]; void prim() { memset(vis,0,sizeof(vis)); memset(dis,10,sizeof(dis)); for(int i=1;i<=n;i++) dis[i]=a[1][i]; vis[1]=1; dis[1]=0; for(int i=1;i<n;i++) { int minn=100000000,s=0; for(int j=1;j<=n;j++) { if(dis[j]<minn&&vis[j]==0) { minn=dis[j]; s=j; } } ans+=minn; vis[s]=1; for(int j=1;j<=n;j++) if(a[s][j]<dis[j]&&vis[j]==0) dis[j]=a[s][j]; } } int main() { //freopen("1.in","r",stdin); n=read();m=read(); memset(a,10,sizeof(a)); for(int i=1;i<=m;i++) { int x,y,z; x=read();y=read();z=read(); a[x][y]=a[y][x]=min(a[x][y],z); } prim(); printf("%d ",ans); return 0; }
回首向来萧瑟处,归去,也无风雨也无晴。