[板子]最小生成树
1 //最小生成树模板 2 //Kruskal算法,稀疏图,复杂度mlogm 3 struct node{int val,fm,to;}edge[M]; 4 bool comp(const node &a,const node &b){return a.val<b.val;} 5 void find(int x){ 6 if(x==fa[x]) return x; 7 return fa[x]=find(fa[x]); 8 } 9 int fa[N]; 10 void Kruskal(){ 11 sort(edge+1,edge+num_bian+1,comp); 12 for(int i=1;i<=n;++i)fa[i]=i; 13 int ans=0; 14 for(int i=1;i<=num_bian;++i){ 15 int x=find(edge[i].fm),y=find(edge[i].to); 16 if(x==y)continue; 17 fa[x]=y;ans+=edge[i].val; 18 //add(x,y,val);//建新图 19 } 20 } 21 //Prim算法,稠密图,复杂度n^2 | mlogn 22 //之所以两个都要记因为看边的数量,可能不优化更快呢 23 void prim(){ 24 memset(d,0x3f,sizeof d); 25 memset(v,0,sizeof v); 26 d[1]=0; 27 for(int i=1;i<n;++i){//相当与枚举边数 28 int x=0; 29 for(int j=1;j<=n;++j) 30 if(!v[j]&&(x==0||d[x]>d[j])) x=j; 31 v[x]=1; 32 for(int y=1;y<=n;++y)if(!v[y]&&dis[x][y]<d[y])d[y]=dis[x][y],pre[y]=x; 33 } 34 /* 35 for(int i=2;i<=n;++i)add(i,pre[i],d[i]),add(pre[i],i,d[i]); 36 这样建边 37 */ 38 } 39 //好像优化不太给力,以后还是尽量用不优化的吧,毕竟稠密图太多边了。 40 struct node{ 41 int val,fm,to; 42 friend bool operator < (const node &a,const node &b){return a.val>b.val;} 43 }; 44 void prim(){ 45 memset(v,0,sizeof v); 46 priority_queue<node>q; 47 for(int i=head[1];i;i=nxt[i])q.push((node){w[i],1,to[i]}); 48 while(!q.empty()&&cnt<=n-1){ 49 node x=q.top();q.pop(); 50 if(v[x.to])continue;v[x.to]=1; 51 add(x.fm,x.to,x.val);add(x.to,x.fm,x.val); 52 cnt++;for(int i=head[x.to];i;i=nxt[i])if(!v[to[i]])q.push((node){w[i],x.to,to[i]}); 53 } 54 }
Keep it simple and stupid.