[Algorithm] The solution of the minimum spanning tree

minimum spanning tree


definition

About the graph with the smallest weight of N points connected by N-1 edges among them


algorithm

prim

Similar to Dijkstra's and greedy ideas
1. Take a point as the starting point to traverse all the points connected to it
2. Add the point with the smallest weight to the minimum spanning tree
3. Modify the weight of the point connected to
it N cycles
Example :
Luogu P3366: Minimum Spanning Tree Template

https://www.luogu.org/problemnew/show/P3366

Code:

#include<iostream>
#include<cstring>
using namespace std;
int g[5005][5005];
int minn[200001];//存蓝点i与白点相连的最小边 
bool exist[5005];//判断是否加入树中 
int n,m,x,y,z;
int tot;
int main()
{
    cin>>n>>m;
    memset(g,127,sizeof(g));
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y>>z;
        //g[x][y]=z;
        //g[y][x]=z;原程序 
        if(z<g[x][y])// 这题有重边所以取最小的边 
        g[x][y]=g[y][x]=z;
    }
    memset(minn,127,sizeof(minn));
    minn[1]=0;//从1开始 
    for(int i=1;i<=n;i++)
    {
        int k=0;
        for(int j=1;j<=n;j++)
        {
            if(exist[j]==0&&minn[k]>minn[j])//找到与白点相连的最小蓝点 
            k=j;
        }
        exist[k]=1;//将蓝点k加入树中 标记为白点 
        tot+=minn[k];//计算权值和 
        for(int j=1;j<=n;j++)
        {
            if(exist[j]==0&&g[k][j]<minn[j])//修改与k相连所有的蓝点 
            minn[j]=g[k][j];
        }
    }
    cout<<tot;
}

kruskal

  1. Use the universal sort to sort the edges from small to large
  2. From small to large, you can merge and use the idea of ​​​​and search until there are N-1 edges
    and search the blog:

https://blog.csdn.net/broken_string_/article/details/79947105

Code:
same as above

#include<iostream>
#include<algorithm>
using namespace std;
struct edge
{
    int l,r,w;//左端点 右端点 权值 
}e[200001];
int father[5001];
int n,m,k=0,tot;
bool cmp(const edge &a,const edge &b)//用权值排序 
{
    if (a.w<b.w) return 1;
    else return 0;
}
int find(int x)
{
    if(father[x]!=x)
    father[x]=find(father[x]);
    return father[x];
}
void unionn(int x,int y)
{
    int fa=find(x);
    int fb=find(y);
    if(fa!=fb)
    father[fa]=fb;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    father[i]=i;
    for(int i=1;i<=m;i++)
    {
        cin>>e[i].l>>e[i].r>>e[i].w;
    }
    sort(e+1,e+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        if(find(e[i].l)!=find(e[i].r))
        {
            unionn(e[i].l,e[i].r);
            tot+=e[i].w;
            k++;
        }
        if(k==n-1) break;//到n-1条时退出 
    }
    cout<<tot;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324407572&siteId=291194637