下面的算法是地杰斯特拉
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define inf 999999999
using namespace std;
int e[1005][1005],dis[100010],p[100010];
int main(){
int i,j,k,m,n,x,y,z;
while(scanf("%d%d",&n,&m)!=EOF){
memset(e,0,sizeof(e));
memset(dis,0,sizeof(dis));
memset(p,0,sizeof(p));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i==j)e[i][j]=0;
else e[i][j]=e[j][i]=inf;
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
e[x][y]=e[y][x]=z;
}
for(i=1;i<=n;i++)
dis[i]=e[1][i];
memset(p,0,sizeof(p));
p[1]=1;
int u;
for(i=1;i<=n-1;i++){
int min=inf;
for(j=1;j<=n;j++){
if(!p[j]&&dis[j]<min){
min=dis[j];
u=j;
}
}
p[u]=1;
for(int v=1;v<=n;v++){
if(e[u][v]<inf){
if(dis[v]>dis[u]+e[u][v]){
dis[v]=dis[u]+e[u][v];
}
}
}
}
for(i=1;i<=n;i++)cout<<dis[i]<<' ';
printf("\n");
}
return 0;
}
/*测试数据如下
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
0 1 8 4 13 17
*/
prim算法和地杰斯特拉算法是一个模子里出来的
就是不停的对各个边进行松弛
记录,用sum加上记录总权值
漏洞就是时间复杂度高及内存空间占得较大
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define inf 999999999
using namespace std;
int a[1010][1010],p[10010],dis[10010],sum;
int main(){
int i,j,k,m,n,x,y,z,end,min;
scanf("%d%d",&m,&n);
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
if(i==j)a[i][j]=0;
else a[i][j]=inf;//每条边的距离初始化为无穷大
for(i=1;i<=n;i++){
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z;//无向图存图
a[y][x]=z;
}
for(i=1;i<=m;i++){
dis[i]=a[1][i];//dis数组存最短距离,再用p数组记录,若p数组记为一,则加上距离;
}
p[1]=1;
int cnt=1;//记录已加上的边的条数
while(cnt<m){//若以有m-1条边,则说明所有边已联通
min=inf;
for(i=1;i<=m;i++){
if(!p[i]&&dis[i]<min){
min=dis[i];//找出离1号点最短的点,值;
end=i;
}
}
p[end]=1;//标记
cnt++;
sum+=dis[end];
for(j=1;j<=m;j++){
if(!p[j]&&dis[j]>a[end][j])dis[j]=a[end][j];//更新
}
}
printf("%d\n",sum);
return 0;
}
可以参看地杰斯特拉的算法~~下面写的是kruscal算法
这个算法用到了并查集,快排
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int fa[100010],sum;
struct node{
int u,v,w;
};
node a[100010];
int cmp(node x,node y){
return x.w<y.w;
}
int father(int x){
return fa[x]=x==fa[x]?x:father(fa[x]);
}
int merge(int x,int y){
int b1=father(x);
int b2=father(y);
if(b1!=b2){
fa[father(x)]=father(y);
return 1;
}
return 0;
}
int main(){
int i,j,k,m,n;
scanf("%d%d",&m,&n);
for(i=1;i<=m;i++){
scanf("%d",&k);
}
for(i=1;i<=n;i++){
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
}
int cnt=0;
sort(a+1,a+n+1,cmp);
//for(i=1;i<=n;i++)cout<<a[i].u<<' '<<a[i].v<<' '<<a[i].w<<endl;
for(i=1;i<=m;i++)fa[i]=i;
for(i=1;i<=n;i++){
if(merge(a[i].u,a[i].v)){
cnt++;
sum+=a[i].w;
}
if(cnt==m-1)break;
//cout<<sum<<endl;
}
if(i==n+1)printf("Impossible\n");
else printf("%d",sum);
return 0;
}
/*
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
*/