Prim算法另一种形式

来源:互联网 发布:深圳阿里云幕布拍照 编辑:程序博客网 时间:2024/06/12 08:13
#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define MAXN 10000#define MAXM 1000#define INF 0X7FFFFFFFstruct node{//1 原图 2 生成树  生成树要存起来int to;int weight;int next;}edge1[MAXM],edge2[MAXM];int head1[MAXN],head2[MAXN];int cnt1,cnt2;int n,m;void Init(){cnt1=0;cnt2=0;memset(edge1,0,sizeof(edge1));memset(head1,0,sizeof(head1));memset(edge2,0,sizeof(edge2));memset(head2,0,sizeof(head2));}void Add(int x,int y,int z,int num){if(num==1){cnt1++;edge1[cnt1].to=y;edge1[cnt1].weight=z;edge1[cnt1].next=head1[x];head1[x]=cnt1;}else{cnt2++;edge2[cnt2].to=y;edge2[cnt2].weight=z;edge2[cnt2].next=head2[x];head2[x]=cnt2;}}void Prim(){int i,j,t;int Min,minIndex,sum=0;int *dis=new int[n];//当前生成树内的点 到树外其他点的最短距离int *parent=new int[n];//生成树中每个节点的父节点for(int i=1;i<=n;i++){dis[i]=INF;}dis[1]=0;//把1节点加入树中 加入树中的,dis均为0parent[1]=0;for(i=1;i<=n;i++){        Min=INF;for(j=1;j<=n;j++){if(dis[j]!=-1&&dis[j]<Min){Min=dis[j];minIndex=j;}}if(Min==INF){//没有最小生成树cout<<"ERROR"<<endl;return;}sum+=dis[minIndex];Add(parent[minIndex],minIndex,dis[minIndex],2);dis[minIndex]=-1;for(t=head1[minIndex];t;t=edge1[t].next){if(dis[edge1[t].to]>edge1[t].weight){dis[edge1[t].to]=edge1[t].weight;parent[edge1[t].to]=minIndex;}}}cout<<sum<<endl;delete dis;}int main(){int x,y,z;cin>>n>>m;for(int i=1;i<=m;i++){cin>>x>>y>>z;Add(x,y,z,1);Add(y,x,z,1);}Prim();return 0;}

可以看出,此算法与单源最短路Dijkstra算法很像,此代码也可以进行堆优化:

#include <cstdio>#include <cstring>#include <queue>#include <iostream>using namespace std;#define INF 0X7FFFFFFFint n,m,cnt,head[1005];struct node{int to;int weight;int next;}edge[10000];struct node1{int to,cost;node1(int x,int y):to(x),cost(y){}bool operator<(node1 a)const{return this->cost>a.cost;}};void Add(int x,int y,int w){cnt++;edge[cnt].to=y;edge[cnt].weight=w;edge[cnt].next=head[x];head[x]=cnt;}void Prim(){//设点从1到Nint sum=0,dis[n+1],book[n+1];priority_queue<node1> q;for(int i=1;i<=n;i++){dis[i]=INF;}dis[1]=0;memset(book,0,sizeof(book));q.push(node1(1,0));while(!q.empty()){node1 t=q.top();q.pop();if(book[t.to]){continue;}sum+=t.cost;//由此可以看出,不加book标记不可以book[t.to]=1;for(int i=head[t.to];i;i=edge[i].next){if(edge[i].weight<dis[edge[i].to]){dis[edge[i].to]=edge[i].weight;q.push(node1(edge[i].to,edge[i].weight));}}}cout<<sum<<endl;}int main(){int x,y,w;cin>>n>>m;for(int i=1;i<=m;i++){cin>>x>>y>>w;Add(x,y,w);Add(y,x,w);}Prim();return 0;}



1 0
原创粉丝点击