@
最小生成树(prime,krusal)模板***
/*------------------------------------------------prim算法---------------------------------------------------*/
#define maxn 1001
#define INF 0x3f3f3f3f
int mp[maxn][maxn];//邻接矩阵
int d[maxn], vis[maxn];//d表示源点到各点的距离,vis表示各点使用情况
int n, m;//点,边
//prim算法构造最小生成树
int prim()
{
for(int i = 1; i <= n; i++)
{
d[i] = mp[1][i];
vis[i] = 0;
}
vis[1] = 1;
int min1, v, ans = 0;
for(int i = 1; i < n; i++) //将集合内的顶点与集合外的顶点所构成的所有边中选取权值最小的一条边
{
//作为生成树的边,并将集合外的那个顶点加入到集合中
min1 = INF;
for(int j = 1; j <= n; j++)//找到最小的权值,标记
{
if(!vis[j] && d[j] < min1)
{
min1 = d[j];
v = j;
}
}
vis[v] = 1;
ans += d[v];
/用集合内的点顶与集合外的顶点构成的边中找最小的边,并将相应的顶点加入集合中如此下去直到全部都加顶点入到集合中,即得最小生成树./
for(int j = 1; j <= n; j++)//更新数组d
{
if(!vis[j] && d[j] > mp[v][j])
{
d[j] = mp[v][j];
}
}
}
return ans;
}
/---------------------------------------------------kruskal算法---------------------------------------------------------/
const int maxn = 1e3;//此处的maxn值可以不同题需要变更。
int p[maxn];
int n,m;//对应的数据.
struct face//存储数据
{
int u,v,w;
} edge[maxn*maxn];
bool cmp(face a,face b)//权值排序
{
return a.w<b.w;
}
void init()//并查集1
{
for(int i=1; i<=n; i++)
p[i]=i;
}
int find(int x)//并查集2
{
return x==p[x]?x:p[x] = find(p[x]);
}
int kruskal()//核心算法
{
int ans=0;
init();
sort(edge,edge+m,cmp);//此处就是将给的权值先排序
for(int i=0; i<m; i++)
{
int x = find(edge[i].u);
int y = find(edge[i].v);
if(x!=y&&edge[i].w)
{
ans+=edge[i].w;
p[x] = y;
}
}
return ans;
}