搜索(未完结版)

前言

图的基础与遍历

图的存储方式

邻接表

List<int []>list[N];

list[x]存储x的所有出点的信息。

list[i][j]={first,second}其中first表示从i出发的某个出点的编号,second表示边权。

list[1]={{2,0},{3,0}}        1这个点有2和3连个出边

邻接矩阵

d[i][j]表示从i到j的边的距离(一般情况下为最短距离)

d[1,2]=0(表示从1到2有一条边)

d[4,3]=-1(不存在对应的边)

DFS(深度优先搜索)

一条道走到黑,走过的路不再走(一种情况尝试到底)

递归

搜索的要点:

1:选定初始状态

2:遍历当前初始状态或状态所产生的合法状态,产生的新状态进入递归

3:检查目标状态是否是合法状态,是则返回,否则继续遍历,重复2-3步骤

常用模板
public static void dfs(){

    if(当前状态==目标状态){
        return;

    }
    for(寻找新状态){
         if(状态合法){
            dfs(新状态);
        }
    }
}

顺序不确定,只要走完就行

回溯

从一条路往前走,能进则进,不能进则退

全排列

回溯的模板与dfs的常用模板相同

public static void dfs(){

    if(当前状态==目标状态){
        return;

    }
    for(寻找新状态){
         if(状态合法){
//标记当前状态已访问
            dfs(新状态);
//撤销标记
        }
    }
}
图论中的模板
boolean<N> v;//v[i]=true说明i点已经走过  标记数组
void dfs(int x){
    v[x]=true;//进来对x,打上标记
    for(int y:list[x]){
        if(v[y]) continue;//已经打过标记的话,跳过
        else dfs(y);//否则进入y这个结点
    }

}

BFS(宽度优先搜索)

一层一层往外走,每个点只走一次

通常用于求边权相等情况下的最短距离

BFS一般用队列来实现

boolean <N> vis;//标记数组,v[i]=true表示点已经走过了
queue<int> q;//q表示带拓展的队列
while(q.size>0){//只要队列不为空就一直走
     int x=q.pop();//弹出来
     if(v[x]) continue;
     v[x]=true;//没有走过这个标记
     for(int y:list[x]){
        q.push(y);
    }//遍历这个点的所有出点,压入队列中

}

编号3891帮派弟位

问题描述

小明在游戏中参加了一个帮派,这一天他突然想知道自己在帮派中是什么地位,但是帮派的查询系统突然坏了,目前只能知道每个人的附属关系,请问你能帮帮他重建关系网并找出他的地位吗?

给定一个正整数 n ,代表该帮派的总人数,并且小明的序号是 m ,给出这 n 个人中每个人的附属关系,确保给出的关系网为一棵树。帮派地位的定义是按照自己手下有多少帮众决定的,注意手下的手下也算是自己的手下。如果手下的帮众相同则按序号较小的在前面。你能帮助小明找到自己的帮派地位吗?

输入格式

第一行,两个正整数 n (1≤n≤105) 和 m (1≤m≤n) ,代表该帮派的总人数以及小明的序号。

接下来 n−1 行,每行两个正整数,格式如下:

  • l r (1≤l,r≤n) , 代表序号为 l 的人附属于序号为 r 的人。
  • 输出格式
    一行,包含 11 个正整数,输出按手下人数多少排序后小明的排名。
  • 样例输入
    6 4 
    2 1 
    3 1 
    4 2 
    5 2 
    6 5 
    

    样例输出

    5

代码

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
   static List<Integer> []list;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan=new Scanner(System.in);
		int n=scan.nextInt();
		int m=scan.nextInt();
		list = new List[n+1];
		for(int i=0;i<n+1;i++) {
			list[i]=new ArrayList<>();
		}//存储点
		int []a=new int [n+1];//存储入度
		for(int i=0;i<n-1;i++) {
			int l=scan.nextInt();
			int r=scan.nextInt();
			list[r].add(l); 
			a[l]++;
		}
		int root=0;
		for(int i=1;i<=n;i++) {//总人数是1-n
			if(a[i]==0) {
				root=i;
        break;
			}
		}//找到根节点了
		int []dp=new int[n+1];//每个结点值的大小
		dfs(root,dp);
		int ans=1;
		for(int i=1;i<m;i++) {
			if(dp[i]>=dp[m]) {
				ans++;
			}//前半部分
		}
		for(int i=m+1;i<n;i++) {
			if(dp[i]>dp[m]) {
				ans++;
			}
		}
		System.out.println(ans);
	}
	public static void dfs(int root,int[] dp) {
		for(int y:list[root]) {
			dfs(y,dp);
			dp[root]+=dp[y]+1;//子节点的子节点数量以及他自己
		}
	}

}

全排列问题(回溯)

问题描述

输入一个数组n,输出1到n的全排列。

代码

package lanqiaoyun;
import java.util.*;

public class quanpai {
	static List<List<Integer>> list=new ArrayList<>();
	//存放全排列
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan=new Scanner(System.in);
		int n=scan.nextInt();
		int []v=new int [n+1];//表示当前数组访问
		List<Integer> res=new ArrayList<>();
		//当前集合存储了多少个元素
		
		dfs(n,v,res);
		for(List<Integer> x:list) {
			for(int y:x) {
				System.out.print(y+" ");
			}
			System.out.println("");
		}
	}
	public static void dfs(int n,int[] v,List<Integer> res) {
		if(res.size()==n) {
			//表示当前集合中已经有n个元素,完成了全排列
			list.add(new ArrayList<>(res));
			return ;
		}
		for(int i=1;i<=n;i++) {
			if(v[i]==1) {
				continue;
			}//不合法,当前数已经被访问过了
			res.add(i);
			v[i]=1;
			dfs(n,v,res);
			res.remove(res.size()-1);
			v[i]=0;
		}
	}

}

相关推荐

  1. 搜索完结

    2024-04-13 06:50:01       14 阅读
  2. 逃离学校(完工

    2024-04-13 06:50:01       20 阅读
  3. Solr完结

    2024-04-13 06:50:01       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-13 06:50:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-13 06:50:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-13 06:50:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-13 06:50:01       20 阅读

热门阅读

  1. Oracle使用regexp_like报错ORA-12733 正则表达式太长

    2024-04-13 06:50:01       17 阅读
  2. 【Leetcode】正则表达式

    2024-04-13 06:50:01       15 阅读
  3. 下采样-Sobel滤波器等边缘检测滤波器

    2024-04-13 06:50:01       15 阅读
  4. 利用Python进行图像和XML标注数据的批量处理

    2024-04-13 06:50:01       13 阅读
  5. Fiddler的安装和使用

    2024-04-13 06:50:01       18 阅读
  6. 如何快速打开Github

    2024-04-13 06:50:01       17 阅读
  7. 【Android】【root & remount】adb su如何添加密码校验

    2024-04-13 06:50:01       19 阅读
  8. python连接mysql数据库通用类

    2024-04-13 06:50:01       17 阅读
  9. 小程序上拉触底节流处理

    2024-04-13 06:50:01       15 阅读
  10. 常用的限流算法原理与实现

    2024-04-13 06:50:01       56 阅读