?晚上好?
在写第八章代码之前,又把2345章的代码又看了一遍,主要针对深度广度优先算法说说注意点吧,其实前面早就提过了,但是反复的过程就是巩固的过程嘛(✔计划通)。
深度优先算法:属于一条路走到黑,再返回,再换一条路走到黑的过程。因为不知道每一条路是不是走的最近最优的,所以一般用一个min变量存储最短路径。dfs往往是单独写一个dfs函数,记录每一步的走向,采用递归的形式一步一步走完全程,所以他必须有1、确认是否到终点,到的话要return 2、确认是否超边界 3、递归函数过后要把当前坐标的标记去除,便于下一次循环 4、循环过后要return
广度优先算法:属于开枝散叶型,一层一层往外扩张,由于前面扩张到的点不会再被扩张到了,他无需去除标记,返回的路径为最快扩张到目标点的路径。与dfs不同,bfs不需要单独列函数,只用在main函数中进行就可以了。通常使用队列的形式,用head和tail指代上一步结点和由该结点扩张到的下一步结点(也就是说tail结点会比head结点多走一步,切记),要注意tail和head加一的位置。
好啦,接下来是第八章的内容!
8.1 最小生成树
import java.util.Scanner;
class Test{
static class edge{
int u;
int v;
int w;
}
static int n,m;
static int[] f=new int[10];
static edge[] e=new edge[10];
public void quicksort(int left,int right){
edge temp=new edge();
int i=left;
int j=right;
if(left>right)
return;
while(i!=j){
while(j>i&&e[j].w>=e[left].w)
j--;
while(i<j&&e[i].w<=e[left].w)
i++;
if(i<j){
temp=e[i];
e[i]=e[j];
e[j]=temp;
}
}
temp=e[left];
e[left]=e[i];
e[i]=temp;
quicksort(left,i-1);
quicksort(i+1,right);
return;
}
public void init(){
for(int i=1;i<=n;i++)
f[i]=i;
}
public int getf(int x){
if(f[x]==x)
return x;
else{
f[x]=getf(f[x]);
return f[x];
}
}
public boolean merge(int x,int y){
if(getf(x)!=getf(y)){
f[getf(y)]=x;
return true; //可合并
}
return false; //不可合并
}
public static void main(String[] args){
Test t=new Test();
Scanner sc=new Scanner(System.in);
System.out.println("请输入点和边的数量");
n=sc.nextInt();
m=sc.nextInt();
System.out.println("请输入各条边的起点、终点和权值");
for(int i=1;i<=m;i++){
e[i]=new edge();
e[i].u=sc.nextInt();
e[i].v=sc.nextInt();
e[i].w=sc.nextInt();
}
t.quicksort(1,m);
t.init();
int sum=0;
int totallength=0;
for(int i=1;i<=m;i++){
if(t.merge(e[i].u,e[i].v)){
sum++;
totallength+=e[i].w;
}
if(sum==n-1) //历经n-1个点
break;
}
System.out.println(totallength);
}
}
/*
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
*/
唉感冒来的太快就像龙卷风,快排之后的return忘掉了调试了好一会。这个的思路是按从小到大顺序排列边,然后把没有连通的最短边加到路径当中,直到n-1条边都被加入,输出路径总和。
8.2 还是最小生成树
一样的题目,换了一种思路。采用一种寻找最短边的形式,把距离当前生成树最短的边加进来,为了保持准确,需要在每一次有点入树的时候都根据新点尝试松弛边。上代码!
import java.util.Scanner;
class Test{
public static void main(String[] args) {
int[][] e = new int[50][50];
int[] book = new int[10];
int[] dis = new int[10];
int n, m, k = 0,inf=99999;
Scanner sc = new Scanner(System.in);
System.out.println("请输入点和边的数量");
n = sc.nextInt();
m = sc.nextInt();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)
e[i][j]=0;
else
e[i][j]=inf;
}
}
System.out.println("请输入相连的点和权值");
for (int i = 1; i <= m; i++) {
int a1 = sc.nextInt();
int a2 = sc.nextInt();
int weigh = sc.nextInt();
e[a1][a2] = weigh;
e[a2][a1] = weigh;
}
book[1] = 1;
int distance=0;
for (int i = 1; i <= n; i++)
dis[i] = e[1][i];
int sum = 1;
while (sum < n) {
int min = 99999;
for (int i = 1; i <= n; i++) {
if (dis[i] < min&&book[i]==0) {
min = dis[i];
k = i;
}
}
book[k]=1;
sum++;
distance+=dis[k];
for (int i = 1; i <= n; i++) {
if (dis[i] > e[k][i])
dis[i] = e[k][i];
}
}
System.out.println(distance);
}
}
/*
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
*/
今天可能想不出第三道了,先说再见吧!