例题

今天做了几个邻接图的问题,总结了一个惯用的套路模板,以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;}
}

【邻接图】解决图的模板相关推荐

  1. 邻接表建立图(c语言)

    邻接表建立图 有向图 无向图 邻接表存图进行拓扑排序 不得不说网上的真的是太乱了,看得我脑壳疼 自己写的可以,感觉好的话可以当成模板. 有向图 代码: #include<stdio.h> ...

  2. 【图论】关于邻接表建图

    邻接表 作为一名现役Oier在做过无数图论题目和搜索题目之后,可以说是相当熟悉了,但是今天做的一道题,让我对于邻接表表示直接懵逼,原来在跑最短路的时候还是明白每个数组各自的作用的,然而一旦在其它题目中 ...

  3. 免费Mac思维导图软件,丰富模板任你选

    思维导图是对思维进行发散整理的工具,也是对内容进行归纳的绝佳方法.对于思维导图而言,它有内外两大功能,向内对已有内容进行总结归纳,形成内容体系:向外它可以对现有主题进行延展,将思路按导图的形式展开. ...

  4. 用邻接表存储图c语言,邻接表、邻接多重表、十字链表及C语言实现

    上一节介绍了如何使用顺序存储结构存储邻接多重表和 邻接的意思是顶点之间有边或者弧存在,通过当前顶点,可以直接找到下一个顶点. 邻接表 使用邻接表存储图时,对于图中的每一个顶点和它相关的邻接点,都存储到 ...

  5. 迪杰斯特拉最全详解(朴素版,堆优化+邻接表存图/链式前向星存图)

    迪杰斯特拉 迪杰斯特拉算法分析 迪杰斯特拉(朴素版) 迪杰斯特拉堆优化(邻接表存图) 迪杰斯特拉堆优化(链式前向星存图) 最短路--spfa(链式前向星存图) 迪杰斯特拉算法分析 一般用三种数据结构存 ...

  6. 邻接表存储图的广度优先遍历

    试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ); 其中LGraph是邻接表存储 ...

  7. 【图专题】三篇图神经网络中的图核函数:主要学习图的拓扑结构从而解决图分类问题...

    导读:Graph kernel可以直观地理解为测量图相似度的函数.它们允许如支持向量机之类的内核化学习算法直接在图上工作,而不需要进行特征提取即可将其转换为固定长度的实值特征向量.一个简单的例子是随机 ...

  8. 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构与算法学习笔记:图...

    图: 图结构区别于线性结构和树型结构,区别可见下图 逻辑上的图(graph)结构由顶点(vertex)和边(edge)组成. 一个图结构G包含顶点集合V和边集合E,任何两个顶点之间可以有一个边表示两者 ...

  9. 邻接表存储图利用BFS遍历

    //今天上机写的邻接表存储图利用BFS遍历: #include<stdio.h> #include<stdlib.h> #include<string.h> #in ...

  10. 图:图的邻接表创建、深度优先遍历和广度优先遍历代码实现

    邻接表介绍 邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构比较较浪费存储空间.如果不想浪费存储空间,大家肯定会先到链表.需要空间的时候再才想内存去申请,同样适用于图 ...

最新文章

  1. SQL 2019——新特征
  2. 网游开发引擎应用分析
  3. 计算机开平方的三种算法
  4. Linux Centos7 测试硬盘IO速度
  5. Note8 android 9 root,红米Note8 MIUI11 安卓9 解账户锁 可登小米账号 永不反锁 完美ROOT 解锁包...
  6. wgs84坐标转换,地图拾取wgs84坐标工具推荐
  7. matlab插值与拟合例题_数学建模matlab插值与拟合
  8. 用火箭送快递?淘宝宣布联合蓝箭航天起启动“宝箭”计划
  9. android win7 共享网络打印机,详解win7共享打印机如何设置
  10. xp计算机重启记录,Windows XP中查看计算机开关机记录
  11. aSRVCC信令流程(振铃中SRVCC)
  12. RAITE Hypervisor介绍
  13. Mac 快捷键符号 斜箭头
  14. 计算n阶逆矩阵的C语言实现
  15. 济南软件著作权申请流程
  16. 微服务网关Gateway(七)
  17. JavaScript自学
  18. 多并发编程基础 之协成
  19. 2022考研真题+汤家凤网课视频。祝2022考研朋友顺利上岸!
  20. A链接点击下载不跳转页面

热门文章

  1. ubuntu设置开机启动图形应用程序,替换默认图形桌面
  2. 【解决方案】Ubuntu设置Matlab桌面启动快捷方式
  3. 桂电计算机信息管理专业课程有哪些,桂林电子工业大学-桂电研究生课程总表91上.doc...
  4. LPC1768以太网控制器
  5. java预研项目_YAML预研文档
  6. 计算机中登录音乐在哪,网易云音乐扫一扫在哪里
  7. 不是吧!你还在手动拉窗帘?
  8. android快速仿花椒,映客直播上下滑动切换直播间
  9. Python之计算π值
  10. assignin与evalin用法理解