图论基本算法其实就6个,两个生成树,4个最短路径。
之前提到过的BFS算法,优点在于不用显式构建整个图,每次找到相邻即可,发现要到达的或者访问完毕即可退出。一般用于只求最短路。
技巧:设置数组,记录每个点的前驱点。
但是对于DFS来说需要显式构建整个图,因为回退的时候还会到之前的点,或者通过另一种方式到达。用于求可行路径总数。
技巧:强大的剪枝........
--------------------------------------------------------------------------------------------------------------------------------------------------
prim
算法核心思想:用集合论的观点来看,则是不断将离这棵树最近的点归约进来。
weight[n] 记录此集合中到各个点(i)的最短距离
adjex[n] 记录此集合中哪个点到各个点(i)的最短距离
visit[n] 记录哪些点属于那个集合 1为此树中,0为未归约进来的点
#include <stdio.h>
#include <string.h>
#define N 401
int state[N][N];
int maps [N][N];
int solve(int n)
{
int weight[N];
int adjex[N];
int visit[N];
int i,j,k;
int minnum,ans;
ans=0;
for(i=0;i<n;i++)
weight[i]=maps[0][i],adjex[i]=visit[i]=0;
visit[0]=1;
for(i=1;i<n;i++)
{
minnum=0xffffff;
for(j=1;j<n;j++)
if(minnum>weight[j] && visit[j] == 0)
minnum=weight[j],k=j;
visit[k]=1;
ans+=minnum;
for(j=1;j<n;j++)
if(maps[k][j]<weight[j] && visit[j]==0 )
weight[j]=maps[k][j],adjex[j]=k;
}
return ans;
}
int main()
{
int i,j,k,n;
while( scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&maps[i][j]);
printf("%d\n",solve(n));
}
return 0;
}
Kruskal
核心思想:不断用最短的边构建生成树,且避免回路。
使用并查集来快速查询一条边的两点是否在同一集合中,避免回路
/*
课堂上,归并的时候以边中最小结