1、目的;算法
找圖中連通全部點的n-1條邊;優化
2、prim算法;spa
1) 將全部點都斷開,而後選擇一個點做爲起始點,V表明已經連通的最小生成樹中的點,S表明不在V裏面的點,每次選擇S中離V最近的點;最終將全部的點加入V中。排序
2) 證實:假設咱們每次加入的那一條邊不是最小邊時的爲最小生成樹,那麼咱們將最小邊加入,會造成一個環,在這個環中任意去掉比最小邊要大的邊構成的生成樹更小,與假設不符,故命題可證it
3)io
#include<stdio.h>map
#define MAX 999999im
int map[10][10];sort
int n,m;di
void init()
{
int i,j;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
map[i][j]=MAX;
for(i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
map[x][y]=z;
map[y][x]=z;
}
}
void prim()
{
int i,j;
int ans=0;
int v[10]={0};
int d[10];
for (i=1;i<=n;i++)
d[i]=map[1][i];
v[1]=1;
for (i=1;i<=n-1;i++)
{
int min=MAX,minj;
for(j=1;j<=n;j++)
if(!v[j]&&min>d[j])
{
min=d[j];
minj=j;
}
v[minj]=1;
ans+=min;
for (j=1;j<=n;j++)
if(!v[j]&&d[j]>map[minj][j])
{
d[j]=map[minj][j];
}
}
printf("Prim : %d\n",ans);
}
int main()
{
init();
prim();
return 0;
}
3、kruskal算法
1) 本算法是經過對全部邊排序以後,從小到大依次添加到最小生成樹中,首先判斷兩點是否在連通,不連通則加入,其判斷用並查集優化。
2)
#include<stdio.h>
#include<algorithm>
using namespace std;
struct Node
{
int v,u,value;
} edge[100];
int f[100];
int n,m;
bool cmp(Node a,Node b)
{
return a.value<b.value;
}
void init()
{
int i,j;
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].value);
sort(edge+1,edge+m+1,cmp);
for (i=1;i<=n;i++) f[i]=i;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
void kruskal()
{
int i;
int ans=0;
for(i=1;i<=m;i++)
{
int x=find(edge[i].u);
int y=find(edge[i].v);
if(x!=y){
ans+=edge[i].value;
f[find(x)]=find(f[y]);
}
}
printf("Kruskal: %d\n",ans);
}
int main()
{
init();
kruskal();
return 0;
}