图论算法之最小生成树 prim//kruskal
最小生成树简单的说就是在一个图里选取一些边,使这些边以及它们所连接的结点组成一棵树(两两结点之间可以到达),并且使选取的边的边权最小。
它的成立条件是图是连通的。并且选取的边数为n-1。(有n个结点,n-1条边,只能为一棵树,没有别的可能)
主要有两个算法:prim和kruskal
prim
【思路】
prim算法写起来和dijkstra很像,因为他们的大体思路是一样的。s[i]表示与i相连的所有边的最小值(条件是这条边的另一端点已经是之前扩展过的)。每一次找到s值最小的点,用它去扩展和他相连的所有的边的另一结点,经过n-1此操作,就可以完成对所有点和边的扩展。
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,i,j,Min,minj,tot;
int a[105][105],s[105];
bool b[105];
int main()
{
scanf("%d",&n);
for (i=1;i<=n;++i)
for (j=1;j<=n;++j)
scanf("%d",&a[i][j]);
for (i=1;i<=n;++i)
s[i]=0x7777777;
s[1]=0;
for (i=1;i<=n-1;++i)
{
Min=0x7777777;
for (j=1;j<=n;++j)
if (!b[j]&&s[j]<Min)
{
Min=s[j];
minj=j;
}
b[minj]=true;
for (j=1;j<=n;++j)
if (!b[j]&&a[minj][j]<s[j])
s[j]=a[minj][j];