美团2024春招第9场算法第二题
测试用例
3 3
1 2 3
3 4 5
4 3 6
目标答案:19
最短路问题
考虑使用dijkstra
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
public class mt2 {
static int n,m;
static StreamTokenizer stk = new StreamTokenizer(new java.io.BufferedReader(new java.io.InputStreamReader(System.in)));
static int[][] graph = new int[1050][1050];
static boolean[][] vis = new boolean[1050][1050];
//构建一个点图
static int getInt(){
try{
stk.nextToken();
return (int)stk.nval;
}catch(Exception e){
return -1;
}
}
public static void main(String[] args) {
n = getInt();
m = getInt();
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
graph[i][j] = getInt();
}
}
node end = new node((1+n)/2, (1+m)/2, graph[(1+n)/2][(1+m)/2]);//在中点相见
long sum = 0;
node start = new node(1,1,graph[1][1]);
sum += dijkstra(start,end);
start = new node(n,m,graph[n][m]);
sum += dijkstra(start,end);
System.out.println(sum - graph[(1+n)/2][(1+m)/2]);//因为中心点会被同时算两次,去重
}
static class node{
int x;
int y;
int value;
public node(int x, int y, int value){
this.x = x;
this.y = y;
this.value = value;
}
}
static long dijkstra(node start,node end){{
long sum = start.value;
PriorityQueue<node> pq = new PriorityQueue<>((a,b)->b.value-a.value);
pq.add(start);
while(!pq.isEmpty()){
node now = pq.poll();
if(now.x == end.x && now.y == end.y) break;//检查是否到达终点
if(vis[now.x][now.y])continue;
vis[now.x][now.y] = true;//标记访问
int[][] path = {{0,1},{0,-1},{1,0},{-1,0}};//上下左右
int x = now.x;
int y = now.y;
long max = Integer.MIN_VALUE;
long max_value = 0;
for(int i = 0; i < 4;i++){
int idx = x + path[i][0];
int idy = y + path[i][1];
if(max < graph[idx][idy] + sum){//如果当前点+总和大于最大值,则更新最大值
max = graph[idx][idy] + sum;
if(!vis[idx][idy]){
max_value = graph[idx][idy];//保存当前点的值,必须是未访问过的
pq.add(new node(idx,idy,graph[idx][idy]));//添加进队列中
}
}
}
sum += max_value;
}
return sum;
}
}
}
关于dijkstra堆优
static void Dijkstra(int s){//堆优化版本
Arrays.fill(dist,Integer.MAX_VALUE);
dist[s] = 0;
//压入格式为{v,w}
PriorityQueue<node> que = new PriorityQueue<>((a,b) -> a.weight - b.weight);//从小到大使用优先队列
que.offer(new node(s,0));
while(!que.isEmpty()){
node now_point = que.poll();
int u = now_point.ponit;
int w = now_point.weight;
if(vis[u]) continue;//将该点置为已访问
vis[u] = true;
//遍历该点的所有邻接点
for(int i = head[u]; i != -1; i = edges[i].next){;
int v = edges[i].to;//到达点
//如果dist[到达点] > 当前点的最短距离+到达下一个点的距离 置换
if(dist[v] > w + edges[i].weight){
dist[v] = w + edges[i].weight;
if(!vis[v]){
que.offer(new node(v,dist[v]));
}
}
}
}
}
已经写的很详细了,不在赘述
#美团2024春招#
查看2道真题和解析