kruskal模板 (最短路)

版权声明:本文为博主原创文章,转载请注明出处~~ https://blog.csdn.net/hxc2101/article/details/81953724

运行时注意编译不通过的那几行中的注释,与题目有关

做题以后可以再留意一下注释

O(\left | E \right |log\left | V \right |) + sort 边的时间 :

//并查集
int pre[maxn],rnk[maxn];  //要的是结点数的范围
inline void init(int n) {for(int i=0;i<=n;i++) pre[i]=i,rnk[i]=0;} //注意这里可能 会需要改一下 i 的范围
inline int find(int x)
{
    int r=x,i=x,j;
    while(pre[r]!=r) r=pre[r];
    while(i!=r) {j=pre[i];pre[i]=r;i=j;} rnk[r]=2;
    return r;
}
inline void join(int x,int y)
{
    int a=find(x),b=find(y);
    if(a==b) return;
    if(rnk[a]<rnk[b]) pre[a]=b;
    else {pre[b]=a;  if(rnk[a]==rnk[b]) rnk[a]++;}
}


//kruskal
//int Ver,E; //顶点数和边数 可以直接把输入的顶点数和边数的变量设为V,E 或 n,m最后赋值一下
init(Ver); //并查集的初始化 需要放在主函数(或多组)内的最前面,可能要输入部分路原已经连通,但初始化太晚,使这些信息 (已经join的) 又被初始化掉了
struct Edg {int u,v,d;}edg[maxn];  //要的是 边数的范围
inline bool cmp(Edg a,Edg b)  {return a.d<b.d;}
inline int kruskal()
{
    sort(edg,edg+E,cmp);  //edg下标是从0开始的还是1开始的?
    int ans=0;
    for(int i=0;i<E;i++)  //edg下标是从0开始的还是1开始的?
    {
        Edg tmp=edg[i];
        if(find(tmp.u)!=find(tmp.v))
        {
            join(tmp.u,tmp.v);
            ans+=tmp.d;
        }
    }
    return ans;
}

猜你喜欢

转载自blog.csdn.net/hxc2101/article/details/81953724
今日推荐