[675. 为高尔夫比赛砍树] dijkstra算法
import java.util.*;
class Solution {
public int cutOffTree(List<List<Integer>> forest) {
int m = forest.size();
int n = forest.get(0).size();
int[][][][] f = new int[m][n][m][n];
int max = m * n;
init(forest, m, n, f);
// floyd(forest, n, f, max);
List<int[]> list = new ArrayList<>();
list.add(new int[]{0,0,0});
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int val = forest.get(i).get(j);
if( val > 1){
list.add(new int[]{i,j,val});
}
}
}
Collections.sort(list, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[2] - o2[2];
}
});
int ans = 0;
for(int i=0;i<list.size()-1;i++){
int[] val = list.get(i);
int x = val[0];
int y = val[1];
int[] nextVal = list.get(i+1);
int tmp = dijkstra(forest,x,y,f,nextVal[0],nextVal[1]);
if(tmp == -1){
return -1;
}
ans += tmp;
}
return ans;
}
public int dijkstra(List<List<Integer>> forest,int x,int y ,int[][][][] f,int nextx,int nexty){
PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[2] - o2[2];
}
});
queue.offer(new int[]{x,y,0});
int m = forest.size();
int n = forest.get(0).size();
boolean[][] visited = new boolean[m][n];
visited[x][y] = true;
while( !queue.isEmpty()) {
int[] node = queue.poll();
if( node[2] == Integer.MAX_VALUE){
continue;
}
if(node[0] == nextx &&node[1] == nexty){
return f[x][y][nextx][nexty];
}
int[][] dirs = new int[][]{
{0, 1}, {0, -1},
{-1, 0}, {1,0}
};
for (int i = 0; i < 4; i++) {
int newx = node[0] + dirs[i][0];
int newy = node[1] + dirs[i][1];
if (newx >= 0 && newx < m && newy >= 0 && newy < n && !visited[newx][newy] && forest.get(newx).get(newy)!=0) {
visited[newx][newy] = true;
int xk = node[0];
int yk = node[1];
f[x][y][newx][newy] = f[x][y][xk][yk]+1;
queue.add(new int[]{newx,newy,f[x][y][newx][newy]});
}
}
}
return -1;
}
private void floyd(List<List<Integer>> forest, int n, int[][][][] f, int max) {
for (int k = 0; k < max; k++) {
int val = forest.get(k/ n).get(k% n);
if( val == 0){
continue;
}
for (int i = 0; i < max; i++) {
if (f[i / n][i % n][k / n][k % n] == Integer.MAX_VALUE) {
continue;
}
val = forest.get(i/ n).get(i% n);
if( val == 0){
continue;
}
for (int j = 0; j < max; j++) {
if (f[k / n][k % n][j / n][j % n] == Integer.MAX_VALUE) {
continue;
}
f[i / n][i % n][j / n][j % n] = Math.min(f[i / n][i % n][j / n][j % n], f[i / n][i % n][k / n][k % n] + f[k / n][k % n][j / n][j % n]);
}
}
}
}
private void init(List<List<Integer>> forest, int m, int n, int[][][][] f) {
int[][] dirs = new int[][]{
{0, 1}, {0, -1},
{-1, 0}, {1,0}
};
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int ii = 0; ii < m; ii++) {
for (int jj = 0; jj < n; jj++) {
f[i][j][ii][jj] = Integer.MAX_VALUE;
if (i == ii && jj == j) {
f[i][j][i][j] = 0;
}
}
}
}
}
for (int x = 0; x < m; x++) {
for (int y = 0; y < n; y++) {
for (int d = 0; d < 4; d++) {
int newx = x + dirs[d][0];
int newy = y + dirs[d][1];
if (newx >= 0 && newx < m && newy >= 0 && newy < n) {
int v1 = forest.get(x).get(y);
int v2 = forest.get(newx).get(newy);
if (v1 == 0 || v2 == 0) {
f[x][y][newx][newy] = Integer.MAX_VALUE;
f[newx][newy][x][y] = Integer.MAX_VALUE;
} else {
f[x][y][newx][newy] = 1;
f[newx][newy][x][y] = 1;
}
}
}
}
}
}
}
[675. 为高尔夫比赛砍树] dijkstra算法的更多相关文章
- Leetcode 675.为高尔夫比赛砍树
为高尔夫比赛砍树 你被请来给一个要举办高尔夫比赛的树林砍树. 树林由一个非负的二维数组表示, 在这个数组中: 0 表示障碍,无法触碰到. 1 表示可以行走的地面. 比1大的数 表示一颗允许走过的树的高 ...
- [Swift]LeetCode675. 为高尔夫比赛砍树 | Cut Off Trees for Golf Event
You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-nega ...
- [LeetCode] 675. Cut Off Trees for Golf Event 为高尔夫赛事砍树
You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-nega ...
- [LeetCode] Cut Off Trees for Golf Event 为高尔夫赛事砍树
You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-nega ...
- 经典树与图论(最小生成树、哈夫曼树、最短路径问题---Dijkstra算法)
参考网址: https://www.jianshu.com/p/cb5af6b5096d 算法导论--最小生成树 最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树. im ...
- Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解
/* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...
- Dijkstra算法(二)之 C++详解
本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...
- 【Python排序搜索基本算法】之Dijkstra算法
Dijkstra算法和前一篇的Prim算法非常像,区别就在于Dijkstra算法向最短路径树(SPT)中添加顶点的时候,是按照ta与源点的距离顺序进行的.OSPF动态路由协议就是用的Dijkstra算 ...
- Cocos2d-x 地图步行实现1:图论Dijkstra算法
下一节<Cocos2d-x 地图行走的实现2:SPFA算法>: http://blog.csdn.net/stevenkylelee/article/details/38440663 本文 ...
- 最短路径算法——Dijkstra算法
在路由选择算法中都要用到求最短路径算法.最出名的求最短路径算法有两个,即Bellman-Ford算法和Dijkstra算法.这两种算法的思路不同,但得出的结果是相同的. 下面只介绍Dijkstra算法 ...
随机推荐
- 关于19c RU补丁报错问题的分析处理
本文演示关于19c RU补丁常见报错问题的分析处理: 1.查看补丁应用失败的原因 2.问题解决后可继续应用补丁 3.发现DB的RU补丁未更新 4.opatchauto应用DB补丁报错解决 1.查看补丁 ...
- 详解 & 0xff 的意义及作用
首先我们要都知道, &表示按位与,只有两个位同时为1,才能得到1, 0x代表16进制数,0xff表示的数二进制1111 1111 占一个字节.和其进行&操作的数,最低8位,不会发生变化 ...
- ABC 306
前三题过水. D \(dp[i][j]\) 表示吃完前 \(i\) 个菜,胃的状况为 \(j\)(\(0\) 是健康,\(1\) 是不好)所获得的最大美味值. E 暴力的平衡树.用 multiset ...
- JS leetcode 猜数字 题解分析,我以为题目在第八层我在第一层,其实我在第三层题目在第一层
壹 ❀ 引 今天来做一道简单到让我一度怀疑题目本意的题目,题目来自leetcode LCP 01. 猜数字,题目描述如下: 小A 和 小B 在玩猜数字.小B 每次从 1, 2, 3 中随机选择一个,小 ...
- 复习一下JVM内存结构
一.程序计数器 程序计数器内存很小,可以看作是当前线程所执行字节码的行号指示器. 有了它,程序就能被正确的执行. 因为有线程切换的存在,则每个线程必须有各自独立的程序计数器,即线程私有的内存. 这里再 ...
- Js中fetch方法
Js中fetch方法 fetch()方法定义在Window对象以及WorkerGlobalScope对象上,用于发起获取资源的请求,其返回一个Promise对象,这个Promise对象会在请求响应后被 ...
- Swoole从入门到入土(16)——WebSocket服务器[事件]
WIKI: 问:websocket协议虽然和http协议不同,但是兼容于http协议,如何判断客户端连接使用的是http协议? 答:通过使用 $server->connection_info($ ...
- 将字符串"a,b,c"以逗号分隔转换为数组并打印
主要利用了String的split方法. package com.dylan.test; /** * @author xusucheng * @create 2017-12-22 **/ public ...
- 以二进制文件安装K8S之部署Node服务
概述 在Node上需要部署Docker.kubelet.kube-proxy,在成功加入Kubernetes集群后,还需要部署CNI网络插件.DNS插件等管理组件. 本节以将192.168.3.138 ...
- RK3588开发笔记(二):基于方案商提供sdk搭建引入mpp和sdk的宿主机交叉编译Qt5.12.10环境
前言 上一篇项目已经构建好了Qt,板子接入mipi屏幕也跑起来了,Qt也能正常运行了,现在需要接入定制开发的sdk,sdk中使用了硬解码等资源涉及到bsp的mpp,所以下一步就是引入mpp和sdk ...