poj 1751 Highways prim算法

来源:互联网 发布:1216nfh网络扫描驱动 编辑:程序博客网 时间:2024/04/19 18:11

题目的大意就是说给你几个点的坐标,并且有几个点之间路是已经修好了的,让你加入其他的边,使得边权和最小,最小生成树的问题,只是初始给了你固定的几条边而已。用prim算法比较好,因为prim算法比较适合稠密图,kruskal算法更适合稀疏图,而这个图每个点之间都要求长度,边比较多。

好了 上代码;

<span style="font-size:14px;">#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int dp[1000][1000];int dup[1000];int dis[10000];int vis[1000];int x[1000],y[1000];int n;int prim(){    int i,next,k;    int count=0;    for(int i=1;i<=n;i++)    {        dis[i]=dp[1][i];        dup[i]=1;//此时是dis存的值全部是1到各个点的距离    }        vis[1]=1;        count++;        while(count<n)        {            int min=0x3f3f3f;            for(i=1;i<=n;i++)            {                if(!vis[i]&&dis[i]<min)                {                    min=dis[i];                    next=i;                }            }            if(dp[dup[next]][next])                {                    printf("%d %d\n",dup[next],next);                }            vis[next]=1;//更新点            count++;            for(i=1;i<=n;i++)            {                if(!vis[i]&&dis[i]>dp[next][i])                {                   dis[i]=dp[next][i];                   dup[i]=next;//用dup[i]=next表示如果此时是i与next相连                }            }        }}int main(){    while(scanf("%d",&n)!=EOF)    {        memset(vis,0,sizeof(vis));        for(int i=1;i<=n;i++)        {            scanf("%d %d",&x[i],&y[i]);        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                if(i==j)                    dp[i][j]=0;                else                {                    dp[i][j]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);                    dp[j][i]=dp[i][j];                }            }        }        int m;        scanf("%d",&m);        for(int i=1;i<=m;i++)        {            int x1,x2;            scanf("%d %d",&x1,&x2);                dp[x1][x2]=dp[x2][x1]=0;//直接把给的边权值等于0        }        prim();    }    return 0;}</span>



0 0