1:Prim
const int INF = 2000000000;
#define MAXN 1001
typedef int elem_t;
/* 1开始编号,n为点数,-INF为不能为生成树*/
elem_t prim(elem_t graph[MAXN][MAXN], int n)
{
bool visit[MAXN]={0};
int mark;
elem_t dis[MAXN];
elem_t ans = 0;
elem_t minnum;
int i, j;
visit[1] = 1;
for(i = 1;i <= n;i ++)
dis[i] = graph[1][i];
for (i = 1; i < n; i ++)
{
minnum = INF;
mark = -1;
for(j = 1;j <= n;j ++)
{
if(!visit[j] && dis[j] < minnum)
{
minnum = dis[j];
mark = j;
}
}
if (mark == -1)
return -INF;
visit[mark] = true;
ans += minnum;
for(j = 1;j <= n;j ++)
{
if(!visit[j] && graph[mark][j] < dis[j])
dis[j] = graph[mark][j];
}
}
return ans;
}
2:Kruscal
const int INF = 2000000000;
const int N = 0xfffff;
#define MAXN 1001
typedef int elem_t;
int p[N], r[N];
int find(int x)
{
return p[x] == x ? x : p[x] = find( p[x] );
}
void merge(int x,int y)
{
int fx,fy;
fx = find(x);
fy = find(y);
if(fx != fy) p[fx] = fy;
}
elem_t cmp(const elem_t i,const elem_t j) { return w[i] < w[j];}
elem_t Kruskal(elem_t w[], int u[], int v[],int m)
{
elem_t ans = 0;
for(int i = 0; i < m; ++i) p[i] = i;
sort(p, p + m, cmp);/*间接排序*/
for(int i = 0; i < m; ++i)
{
int e = p[i];
elem_t x = find( u[e] );
elem_t y = find( v[e] );
if(x != y){ ans += w[e]; merge(x,y); }
}
return ans;
}
本文详细介绍了两种经典的最小生成树算法——Prim算法和Kruskal算法。Prim算法通过选择距离最近的顶点来逐步构建生成树,而Kruskal算法则是按边的权重从小到大排序,依次加入不构成环的边。这两种算法都广泛应用于图论中解决网络设计等问题。
1403

被折叠的 条评论
为什么被折叠?



