算法思路挺简单的,之前的prim都是用了邻接表+优先队列,但是这个最初的写法还是挺有用的。O(v^2)的复杂度,求次小生成树的时候,prim貌似是最好的选择。
krukstra不需要考虑重边的问题,但是prim要考虑。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define res register int
const int maxn=5005;
int low[maxn];//记录每一个未遍历的点到已经在生成树上点的最短距离。
int dis[maxn][maxn];//记录距离
int N,M;
int vis[maxn];
int prim()
{
int ans=0;
for(res i=1;i<=N;i++)
low[i]=dis[1][i];
vis[1]=1;
for(res i=1;i<N;i++){
int minc=inf;
int c=-1;
for(res j=1;j<=N;j++){
if(!vis[j]&&low[j]<minc){
minc=low[j];
c=j;
}
}
if(inf==minc) return -1;
ans+=minc;
vis[c]=1;
for(res j=1;j<=N;j++)
if(!vis[j]&&low[j]>dis[c][j])
low[j]=dis[c][j];
}
return ans;
}
int main()
{
scanf("%d%d",&N,&M);
memset(dis,inf,sizeof(dis));
for(res i=0;i<=N;i++)
dis[i][i]=0;
int a,b,c;
for(res i=0;i<M;i++){
scanf("%d%d%d",&a,&b,&c);
if(c<dis[a][b])
dis[a][b]=dis[b][a]=c;//去重边
}
int ans=p();
if(-1!=ans) printf("%d",ans);
else printf("orz");
return 0;
}