AcWing 858. Prim算法求最小生成树

AcWing 858. Prim算法求最小生成树_第1张图片

https://www.acwing.com/problem/content/860/

这道题可以这样理解,在一个图(别人管这叫集合)里面(图论嘛,类似于路线图)中选出所有的点,用n-1条线段,把这些点都连着,题意很好理解,我也当时想着用贪心的思路来做,后来发现并不是很好做,然后我就看了y总的做法,也是根据贪心提出了一个prim的算法,y总可能讲的不是很仔细,但是思路是没有错的,我看了b站的视频,确实有助于理解,于是我也拿出来给大家看,这个视频尽量多看几遍,这是原理。

https://www.bilibili.com/video/BV1Ma4y1W7pJ?from=search&seid=2724484141940561544

主要的意思就是,st[i]保存的节点看作一个集合,然后去扩散下一个点,居然和迪杰特斯拉算法有异曲同工之处,y总dist[i]没说清,我觉得根据题意来说,dist[i]应该是离上一个点牵着的距离(我也不是很清楚)dist会随着算法变化,因为新增了st,所以根据这些点进行扩散,我的话都是根据视频去说。代码中很细节的地方我都注释了。

#include
#include
#include

using namespace std;

const int N=510,M=1e5+10,Inf=0x3f3f3f3f;

int g[N][N],dist[N];
bool st[N];
int n,m;

int prim()
{
     
   int res=0;
   memset(dist,0x3f,sizeof dist);
   for(int i=0;i<n;i++)
   {
     
       int t=-1;
       for(int j=1;j<=n;j++)
       {
     
           if(!st[j]&&(t==-1||dist[t]>dist[j]))//这个表示找离已经保存的点最近的距离。
           t=j;
       }
      // cout<
       if(i&&dist[t]==Inf) return Inf;//说明没有到t点的路线,t是孤立点。
       if(i) res+=dist[t];//加n-1次,这又是一个小细节哦,然后dist[t]要找的最小距离。
       for(int j=1;j<=n;j++)
       {
     
           dist[j]=min(dist[j],g[t][j]);
       }
       st[t]=true;
   }
   return res;
}


int main(void)
{
     
    memset(g,0x3f,sizeof g);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
     
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        g[a][b]=min(g[a][b],c);
        g[b][a]=min(g[b][a],c);
    }
    int t=prim();
    if(t==Inf) puts("impossible");
    else
    cout<<t;
}

你可能感兴趣的:(acwing,图论)