这一篇也是帮助我记模板的文章呢
1 Kruskal 并查集只与边有关,用于稀疏图。
struct edge
{
int begin,end,len;//起点 终点 长度
}xhd[maxn];
bool cmp(struct edge a, struct edge b)
{
return a.len<b.len;
}
void makeset()//初始化
{
for(int i=1;i<=n;i++) pre[i]=i;
}
int find(int x)
{
if(x!=pre[x]) pre[x]=find(pre[x]);
return pre[x];
}
void union(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy) pre[fy]=fx;
}
int Kruskal()
{
int ans=0,cnt=0;
makeset();
sort(xhd,xhd+m,cmp)//将边按长度从短到长排序,m是边的数量。
for(int i=0;i<m;i++)
{
if(find(xhd[i].begin)!=find(xhd[i].end))
{
union(xhd[i].begin,xhd[i].end);
ans+=xhd[i].len;
cnt++;//最小生成树的边的个数;
}
}
//这里没有考虑成环的情况。
if(cnt==n-1) //最小生成树条件:边数=顶点数-1
{
return ans;
}
return -1;//边不够
}
2 Prim 只与点有关 适合稠密图。
void Prim()
{
for(int i=1;i<=n;i++)
{
vis[i]=0;
dis[i]=map[start][i];
}
vis[start]=0;
int sum=0;
for(int k=1;k<n;k++)
{
int mi=inf,pos=0;
for(int i=1;i<=n;i++)
{
if(!vis[i]&&dis[i]<mi)
{
mi=dis[i]; pos=i;
}
}
vis[pos]=1;
sum+=dis[pos];
for(int i=1;i<=n;i++)
{
if(!vis[i]&&map[pos][i]<dis[i])
{
dis[i]=map[pos][i];
}
}
}
printf("%d\n",sum);
}