prim及其:队列优化

来源:互联网 发布:javascript给div赋值 编辑:程序博客网 时间:2024/05/10 13:08

prim:

//矩阵输入的prim  有n*n的矩阵,求最小生成树#include<stdio.h>#include<string.h>#define spot 1000const int inf=0x3f3f3f3f;int a[spot+10][spot+10],dis[spot+10],b[spot+10];  //a[][]存矩阵,b[]标记,dis[]距离int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        int sum=1,s=0,i,j;        for(i=1; i<=n; i++)            for(j=1; j<=n; j++)                scanf("%d",&a[i][j]);        memset(b,0,sizeof(b));        for(i=1; i<=n; i++)            dis[i]=a[1][i];        dis[1]=0;        b[1]=1;        while(sum<n)        {            int minn=inf,u;            for(i=1; i<=n; i++)                if(!b[i]&&minn>dis[i])                    minn=dis[i],u=i;            b[u]=1,sum++,s+=dis[u];            for(i=1; i<=n; i++)                if(!b[i]&&a[u][i]<dis[i])                    dis[i]=a[u][i];        }        printf("%d\n",s);    }    return 0;}

prim队列优化

#include<iostream>#include<cstdio>#include<queue>#include<cstring>#include<vector>#include<algorithm>using namespace std;struct zp{    int s;    int e;    int l;    bool friend operator<(zp a,zp b)    {        return a.l>b.l;    }};int main(){    int n,m;    while(~scanf("%d%d",&n,&m))//n个点m条边    {        vector<zp> node[100010];        int a,b,c;        zp tmp;        for(int i = 0; i < m; i++)//建图        {            scanf("%d%d%d",&a,&b,&c);            tmp.s=a;            tmp.e = b;            tmp.l = c;            node[a].push_back(tmp);            tmp.s=b;            tmp.e = a;            node[b].push_back(tmp);        }        int vis[100010];        memset(vis,0,sizeof(vis));        priority_queue<zp>q;        vis[1]=1;        int l=node[1].size();        for(int i=0; i<l; i++)        {            zp ff;            ff=node[1][i];            q.push(ff);        }        int sum=0,cont=0;        while(cont!=n-1)//找到n-1条边跳出循环        {            zp ss=q.top();//优先队列选择离走过点的最小距离            q.pop();            if(vis[ss.e])//走过的点不算                continue;            sum+=ss.l;//加上权值            cont++;//多加一条边            vis[ss.e]=1;            int l=node[ss.e].size();            for(int i=0; i<l; i++)//遍历选择的最近距离点的所有边            {                if(!vis[node[ss.e][i].e])//如果没走过入队                {                    zp ff;                   ff=node[ss.e][i];                    q.push(ff);                }            }        }        printf("%d\n",sum);    }}


0 0