最小生成树Prim算法详解
http://www.cnblogs.com/Veegin/archive/2011/04/29/2032388.html
仅提炼模版
如下:
POJ1258
#include <stdio.h>
#include <string.h>
#define MaxInt 0x3f3f3f3f
#define N 110
//创建map二维数组储存图表,low数组记录每2个点间最小权值,visited数组标记某点是否已访问
int map[N][N],low[N],visited[N];
int n;
int prim()
{
int i,j,pos,min,result=0;
memset(visited,0,sizeof(visited));
//从某点开始,分别标记和记录该点
visited[1]=1;pos=1;
//第一次给low数组赋值
for(i=1;i<=n;i++)
if(i!=pos) low[i]=map[pos][i];
//再运行n-1次
for(i=1;i<n;i++)
{
//找出最小权值并记录位置
min=MaxInt;
for(j=1;j<=n;j++)
if(visited[j]==0&&min>low[j])
{
min=low[j];pos=j;
}
//最小权值累加
result+=min;
//标记该点
visited[pos]=1;
//更新权值
for(j=1;j<=n;j++)
if(visited[j]==0&&low[j]>map[pos][j])
low[j]=map[pos][j];
}
return result;
}
int main()
{
int i,v,j,ans;
while(scanf("%d",&n)!=EOF)
{
//所有权值初始化为最大
memset(map,MaxInt,sizeof(map));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&v);
map[i][j]=map[i][j]=v;
}
ans=prim();
printf("%d\n",ans);
}
return 0;
}
Kruskal算法
http://www.cnblogs.com/tonghao/p/4671746.html
#include<stdio.h>
#include<algorithm>
using namespace std;
int set[110];
struct record
{
int beg;
int end;
int money;
}s[11000];
int find(int fa) //查找根节点
{
int ch=fa;
int t;
while(fa!=set[fa])
fa=set[fa];
while(ch!=fa)
{
t=set[ch];
set[ch]=fa;
ch=t;
}
return fa;
}
void mix(int x,int y) //合并两点
{
int fx,fy;
fx=find(x);
fy=find(y);
if(fx!=fy)
set[fx]=fy;
}
bool cmp(record a,record b)
{
return a.money<b.money; //对价格进行排序
}
int main()
{
int city,road,n,m,j,i,sum;
while(scanf("%d",&road)&&road!=0)
{
scanf("%d",&city);
for(i=0;i<road;i++)
{
scanf("%d%d%d",&s[i].beg,&s[i].end,&s[i].money);
}
for(i=1;i<=city;i++)
set[i]=i; //初始化set[]数组
sort(s,s+road,cmp);
sum=0;
for(i=0;i<road;i++) //这个地方可能不好理解 我在下面作出解释
{
if(find(s[i].beg)!=find(s[i].end)) //当两点没有连接时才可以连接两点
{
mix(s[i].beg,s[i].end); //因为已经按照价钱从高到低排序好了所以可以找到
sum+=s[i].money; //在两个点 未相连的情况下的最小权值并将其相连
}
}
j=0;
for(i=1;i<=city;i++)
{
if(set[i]==i)
j++;
if(j>1)
break;
}
if(j>1) //如果根节点不只一个则证明此组数据不是一棵树
printf("?\n");
else
printf("%d\n",sum);
}
return 0;
}
不成熟的见解:
Prim算法是要在已经遍历过的图的基础上找出最小的边,而Kruskal算法主要是找出最小的边,只要不会形成环就经过这条边。
因此,Prim算法的难点在找到与已知图相接的最小边,而Kruskal算法是使用并查集判断是否会形成一个回路。