Kruskal
需要并查集和建边中的高级版本。
变量
- Graph<N,N<<1> Kru:存生成树。
- pair<int,pair<int,int> >a[M]:暂存边的数组。
- int m:边的个数。
函数
- bool ask(int n):求点编号为 1∼n 的无向图的最小生成树,若能生成,则返回真,否则返回假。
代码
struct Kruskal{
Graph<N,N<<1> Kru;
pair<int,pair<int,int> >a[M];
int m;
bool ask(int n){
m=Kru.tot=0;
int cnt=0;
mfs.init(n);
for(int i=1;i<=n;i++){
for(int j=G.head[i];j;j=G.nxt[j]){
int y=G.ver[j];
int z=G.edge[j];
if(i<y)
a[++m]=(make_pair(z,make_pair(i,y)));
}
}
sort(a+1,a+m+1);
for(int i=1;i<=m;i++){
int u=a[i].second.first;
int v=a[i].second.second;
int w=a[i].first;
if(mfs.get(u)!=mfs.get(v)){
mfs.merge(u,v);
cnt++;
Kru.add(u,v,w);
Kru.add(v,u,w);
}
if(cnt==n-1)
return 1;
}
return 0;
}
}tu;
Prim
宏定义
- #define PT int:图的边权类型。
变量
- PT a[N][N]:表示无向图的邻接矩阵。
- PT d[N]:到节点 1 的距离。
- bool v[N]:标记一个点是否已在生成树内。
函数
- PT ask(int n):求点编号为 1∼n 的无向图的最小生成树,返回生成树的边权之和。
代码
#define PT int
PT a[N][N];
struct Prim{
PT d[N];
bool v[N];
PT ask(int n){
memset(d,0x3f,sizeof(d));
memset(v,0,sizeof(v));
d[1]=0;
PT ans=0;
for(int i=1,x;i<n;i++){
x=0;
for(int j=1;j<=n;j++)
if(!v[j]&&(!x||d[j]<d[x]))
x=j;
v[x]=1;
for(int j=1;j<=n;j++)
if(!v[j])
d[j]=min(d[j],a[x][j]);
}
for(int i=2;i<=n;i++)
ans+=d[i];
return ans;
}
}tu;