版权声明:转载请注明出处 https://blog.csdn.net/jay__bryant/article/details/81606246
题意:n个点,n*n的矩阵表示边,求最小生成树
(1)prim O(n^2)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
const int INF = 0x3f3f3f3f;
int g[N][N];
int dis[N];
bool vis[N];
int n;
int prim()
{
int ret = 0;
for(int i = 1; i <= n; ++i) dis[i] = INF;
dis[1] = 0;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; ++i)
{
int mm = INF, p = -1;
for(int j = 1; j <= n; ++j)
if(!vis[j] && dis[j]<mm)
mm = dis[p=j];
if(p==-1) break;
vis[p] = 1;
ret += dis[p];
for(int j = 1; j <= n; ++j)
if(!vis[j])
dis[j] = min(dis[j], g[p][j]);
}
return ret;
}
int main()
{
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
scanf("%d", &g[i][j]);
printf("%d\n", prim());
}
return 0;
}
(2)kruskal O(mlogn)
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 110;
const int M = 10010;
struct node
{
int u, v, w;
node(){}
node(int _u, int _v, int _w)
{
u = _u; v = _v; w = _w;
}
bool operator <(const node &p)const
{
return w<p.w;
}
}edge[M];
int tot;
int fa[N];
int n;
int findf(int x)
{
return x==fa[x]?x:fa[x]=findf(fa[x]);
}
bool merge_(int x, int y)
{
int f1 = findf(x);
int f2 = findf(y);
if(f1==f2) return 0;
fa[f1] = f2;
return 1;
}
int kruskal()
{
sort(edge+1, edge+tot+1);
int ret = 0;
int cnt = 0;
for(int i = 1; i <= tot; ++i)
{
if(merge_(edge[i].u, edge[i].v))
{
++cnt;
ret += edge[i].w;
}
if(cnt==n-1) break;
}
return ret;
}
int main()
{
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; ++i) fa[i] = i;
tot = 0;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
{
int x;
scanf("%d", &x);
if(i>=j) continue;
edge[++tot] = node(i, j, x);
}
printf("%d\n", kruskal());
}
return 0;
}