【邻接图】解决图的模板
例题
今天做了几个邻接图的问题,总结了一个惯用的套路模板,以leetcode1971(双向图、简单)、leetcode1042(双向图、中等)、leetcode997(单向图、简单)为例:
leetcode 1971
有一个具有 n个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。
请你确定是否存在从顶点 start 开始,到顶点 end 结束的 有效路径 。
给你数组 edges 和整数 n、start和end,如果从 start 到 end 存在 有效路径 ,则返回 true,否则返回 false 。
示例 1:
输入:n = 3, edges = [[0,1],[1,2],[2,0]], start = 0, end = 2
输出:true
解释:存在由顶点 0 到顶点 2 的路径:
- 0 → 1 → 2
- 0 → 2
示例 2:
输入:n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], start = 0, end = 5
输出:false
解释:不存在由顶点 0 到顶点 5 的路径.
提示:
1 <= n <= 2 * 105
0 <= edges.length <= 2 * 105
edges[i].length == 2
0 <= ui, vi <= n - 1
ui != vi
0 <= start, end <= n - 1
不存在双向边
不存在指向顶点自身的边
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;class Solution {public boolean validPath(int n, int[][] edges, int start, int end) {//构建邻接图Map<Integer, Set<Integer>> graph = new HashMap<>();for(int i = 0; i < n ; i ++) {graph.put(i, new HashSet<Integer>());}for(int[] edge : edges) {graph.get(edge[0]).add(edge[1]);graph.get(edge[1]).add(edge[0]);}//dfs寻找有效路径boolean[] visited = new boolean[n];return dfs(graph, start, end, visited);}public boolean dfs(Map<Integer, Set<Integer>> graph, int start, int end, boolean[] visited) {//判断条件if(start == end) return true;if(visited[start]) return false;//当前条件visited[start] = true;for(int x : graph.get(start)) {//x为目的地if(dfs(graph, x, end, visited)) return true;}return false;}
}
leetcode 1042
有 n 个花园,按从 1 到 n 标记。另有数组 paths ,其中 paths[i] = [xi, yi] 描述了花园 xi 到花园 yi 的双向路径。在每个花园中,你打算种下四种花之一。
另外,所有花园 最多 有 3 条路径可以进入或离开.
你需要为每个花园选择一种花,使得通过路径相连的任何两个花园中的花的种类互不相同。
以数组形式返回 任一 可行的方案作为答案 answer,其中 answer[i] 为在第 (i+1) 个花园中种植的花的种类。花的种类用 1、2、3、4 表示。保证存在答案。
示例 1:
输入:n = 3, paths = [[1,2],[2,3],[3,1]]
输出:[1,2,3]
解释:
花园 1 和 2 花的种类不同。
花园 2 和 3 花的种类不同。
花园 3 和 1 花的种类不同。
因此,[1,2,3] 是一个满足题意的答案。其他满足题意的答案有 [1,2,4]、[1,4,2] 和 [3,2,1]
示例 2:
输入:n = 4, paths = [[1,2],[3,4]]
输出:[1,2,1,2]
示例 3:
输入:n = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
输出:[1,2,3,4]
提示:
1 <= n <= 104
0 <= paths.length <= 2 * 104
paths[i].length == 2
1 <= xi, yi <= n
xi != yi
每个花园 最多 有 3 条路径可以进入或离开
class Solution {public int[] gardenNoAdj(int n, int[][] paths) {//构建邻接图Set<Integer>[] graph = new Set[n];for(int i = 0; i < n; i ++){graph[i] = new HashSet<Integer>();}for(int[] path : paths) {graph[path[0] - 1].add(path[1] - 1);graph[path[1] - 1].add(path[0] - 1);}int[] res = new int[n];//返回结果//遍历每一个花园for(int i = 0; i < n; i ++) {//遍历当前花园i的所有邻接花园boolean[] used = new boolean[5]; //[0]为true表示已着色,[1]-[4]表示4个颜色是否被使用过for(int neighbor : graph[i]) {used[res[neighbor]] = true;}//给当前花园着色for(int j = 1; j <= 4; j ++) {if(!used[j]) {res[i] = j;used[j] = true;break;}}}return res;}
}
leetcode 997
小镇里有 n 个人,按从 1 到 n 的顺序编号。传言称,这些人中有一个暗地里是小镇法官。
如果小镇法官真的存在,那么:
小镇法官不会信任任何人。
每个人(除了小镇法官)都信任这位小镇法官。
只有一个人同时满足属性 1 和属性 2 。
给你一个数组 trust ,其中 trust[i] = [ai, bi] 表示编号为 ai 的人信任编号为 bi 的人。
如果小镇法官存在并且可以确定他的身份,请返回该法官的编号;否则,返回 -1 。
示例 1:
输入:n = 2, trust = [[1,2]]
输出:2
示例 2:
输入:n = 3, trust = [[1,3],[2,3]]
输出:3
示例 3:
输入:n = 3, trust = [[1,3],[2,3],[3,1]]
输出:-1
提示:
1 <= n <= 1000
0 <= trust.length <= 104
trust[i].length == 2
trust 中的所有trust[i] = [ai, bi] 互不相同
ai != bi
1 <= ai, bi <= n
class Solution {public int findJudge(int n, int[][] trust) {//构建邻接图,set类型的数组,下标i代表当前人,graph[i]这个set集合中都是i信任的人的下标Set[] graph = new Set[n];for(int i = 0; i < n ;i ++){graph[i] = new HashSet<Integer>();}//将所给数据放入到构建的邻接图中for(int[] t : trust){graph[t[0]].add(t[1]);}//遍历邻接图for(int i = 0; i < n; i ++){//第一个条件,不相信任何人if(graph[i].size() == 0){//第二个条件,每个人都信任他boolean flag = true;for(int j = 0; j < n; j ++){if(j == i) continue;//一旦有人不信任他就不可能为法官if(!graph[j].contains(i)) flag = false;}if(flag) return i;}}return -1;}
}
【邻接图】解决图的模板相关推荐
- 邻接表建立图(c语言)
邻接表建立图 有向图 无向图 邻接表存图进行拓扑排序 不得不说网上的真的是太乱了,看得我脑壳疼 自己写的可以,感觉好的话可以当成模板. 有向图 代码: #include<stdio.h> ...
- 【图论】关于邻接表建图
邻接表 作为一名现役Oier在做过无数图论题目和搜索题目之后,可以说是相当熟悉了,但是今天做的一道题,让我对于邻接表表示直接懵逼,原来在跑最短路的时候还是明白每个数组各自的作用的,然而一旦在其它题目中 ...
- 免费Mac思维导图软件,丰富模板任你选
思维导图是对思维进行发散整理的工具,也是对内容进行归纳的绝佳方法.对于思维导图而言,它有内外两大功能,向内对已有内容进行总结归纳,形成内容体系:向外它可以对现有主题进行延展,将思路按导图的形式展开. ...
- 用邻接表存储图c语言,邻接表、邻接多重表、十字链表及C语言实现
上一节介绍了如何使用顺序存储结构存储邻接多重表和 邻接的意思是顶点之间有边或者弧存在,通过当前顶点,可以直接找到下一个顶点. 邻接表 使用邻接表存储图时,对于图中的每一个顶点和它相关的邻接点,都存储到 ...
- 迪杰斯特拉最全详解(朴素版,堆优化+邻接表存图/链式前向星存图)
迪杰斯特拉 迪杰斯特拉算法分析 迪杰斯特拉(朴素版) 迪杰斯特拉堆优化(邻接表存图) 迪杰斯特拉堆优化(链式前向星存图) 最短路--spfa(链式前向星存图) 迪杰斯特拉算法分析 一般用三种数据结构存 ...
- 邻接表存储图的广度优先遍历
试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ); 其中LGraph是邻接表存储 ...
- 【图专题】三篇图神经网络中的图核函数:主要学习图的拓扑结构从而解决图分类问题...
导读:Graph kernel可以直观地理解为测量图相似度的函数.它们允许如支持向量机之类的内核化学习算法直接在图上工作,而不需要进行特征提取即可将其转换为固定长度的实值特征向量.一个简单的例子是随机 ...
- 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构与算法学习笔记:图...
图: 图结构区别于线性结构和树型结构,区别可见下图 逻辑上的图(graph)结构由顶点(vertex)和边(edge)组成. 一个图结构G包含顶点集合V和边集合E,任何两个顶点之间可以有一个边表示两者 ...
- 邻接表存储图利用BFS遍历
//今天上机写的邻接表存储图利用BFS遍历: #include<stdio.h> #include<stdlib.h> #include<string.h> #in ...
- 图:图的邻接表创建、深度优先遍历和广度优先遍历代码实现
邻接表介绍 邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构比较较浪费存储空间.如果不想浪费存储空间,大家肯定会先到链表.需要空间的时候再才想内存去申请,同样适用于图 ...
最新文章
- SQL 2019——新特征
- 网游开发引擎应用分析
- 计算机开平方的三种算法
- Linux Centos7 测试硬盘IO速度
- Note8 android 9 root,红米Note8 MIUI11 安卓9 解账户锁 可登小米账号 永不反锁 完美ROOT 解锁包...
- wgs84坐标转换,地图拾取wgs84坐标工具推荐
- matlab插值与拟合例题_数学建模matlab插值与拟合
- 用火箭送快递?淘宝宣布联合蓝箭航天起启动“宝箭”计划
- android win7 共享网络打印机,详解win7共享打印机如何设置
- xp计算机重启记录,Windows XP中查看计算机开关机记录
- aSRVCC信令流程(振铃中SRVCC)
- RAITE Hypervisor介绍
- Mac 快捷键符号 斜箭头
- 计算n阶逆矩阵的C语言实现
- 济南软件著作权申请流程
- 微服务网关Gateway(七)
- JavaScript自学
- 多并发编程基础 之协成
- 2022考研真题+汤家凤网课视频。祝2022考研朋友顺利上岸!
- A链接点击下载不跳转页面