版权声明:本文为博主原创文章,转载请注明出处~~ https://blog.csdn.net/hxc2101/article/details/81953724
运行时注意编译不通过的那几行中的注释,与题目有关
做题以后可以再留意一下注释
+ 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;
}