CodeForces_1422D Returning Home(最短路)
Returning Home
Problem Description
Yura has been walking for some time already and is planning to return home. He needs to get home as fast as possible. To do this, Yura can use the instant-movement locations around the city.
Let’s represent the city as an area of n × n n×n n×n square blocks. Yura needs to move from the block with coordinates ( s x , s y ) (s_x,s_y) (sx,sy) to the block with coordinates ( f x , f y ) (f_x,f_y) (fx,fy). In one minute Yura can move to any neighboring by side block; in other words, he can move in four directions. Also, there are m m m instant-movement locations in the city. Their coordinates are known to you and Yura. Yura can move to an instant-movement location in no time if he is located in a block with the same coordinate x x x or with the same coordinate y y y as the location.
Help Yura to find the smallest time needed to get home.
Input
The first line contains two integers n n n and m m m — the size of the city and the number of instant-movement locations ( 1 ≤ n ≤ 1 0 9 1≤n≤10^9 1≤n≤109, 0 ≤ m ≤ 1 0 5 0≤m≤10^5 0≤m≤105).
The next line contains four integers s x s_x sx s y s_y sy f x f_x fx f y f_y fy — the coordinates of Yura’s initial position and the coordinates of his home ( 1 ≤ s x , s y , f x , f y ≤ n 1≤s_x,s_y,f_x,f_y≤n 1≤sx,sy,fx,fy≤n).
Each of the next m lines contains two integers x i x_i xi y i y_i yi — coordinates of the i-th instant-movement location ( 1 ≤ x i , y i ≤ n ) (1≤x_i,y_i≤n) (1≤xi,yi≤n).
Output
In the only line print the minimum time required to get home.
Sample Input
5 3
1 1 5 5
1 2
4 1
3 3
Sample Output
5
題意
在一個n*n大小的地圖中,初始在位置 ( s x , s y ) (s_x,s_y) (sx,sy),目標位置為 ( f x , f y ) (f_x, f_y) (fx,fy)。每分鐘可以向上下左右的地圖內區域移動一格。在地圖中有m個瞬移位置,當與這些位置處於同一行或同一列時,可以選擇瞬間傳送到該位置。求最快需要多久到達目標位置。
思路
最短路的最後一步一定是從初始位置或瞬移位置走到目標位置。
可以由瞬移位置的同行或同列瞬間傳送至瞬移位置,所以額外建
2
∗
m
2*m
2∗m個點,
m
m
m個點代表
x
=
x
i
x=x_i
x=xi,
m
m
m個點代表
y
=
y
i
y=y_i
y=yi(將代表
x
=
x
i
x=x_i
x=xi的m個點按升序排列,y同理)。
兩個瞬移點之間的轉移代價主要看其橫縱座標之差。
建圖:
從 初始位置/瞬移位置連邊 到 目標位置 ,代價為兩點間的距離。
從
x
=
x
i
x=x_i
x=xi 到
x
=
x
i
−
1
x = x_{i-1}
x=xi−1,
x
=
x
i
+
1
x=x_{i+1}
x=xi+1,代價為
x
i
−
x
i
−
1
x_i-x_{i-1}
xi−xi−1,
x
i
+
1
−
x
i
x_{i+1}-x_i
xi+1−xi。
從 初始位置 到
x
=
x
i
x=x_i
x=xi,代價為
a
b
s
(
s
x
−
x
i
)
abs(s_x-x_i)
abs(sx−xi)。
從 瞬移位置
j
j
j 到
x
=
x
j
x = x_j
x=xj,代價為0。
y
=
y
i
y=y_i
y=yi與
x
=
x
i
x=x_i
x=xi同理建邊,同時都為雙向邊。
建完圖後跑最短路即可。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<double, int> P;
const int maxn = 300100;
const int mod = 1000000007;
struct node{
int to, w;
node(){}
node(int a, int b):to(a),w(b){}
};
int x[maxn], y[maxn], a[maxn], b[maxn], dis[maxn];
vector<node> g[maxn];
int dijkstra(int n);
void add(int fr, int to, int w);
int main()
{
int n, m, sx, sy, fx, fy, i, j, k;
scanf("%d %d", &n, &m);
scanf("%d %d %d %d", &sx, &sy, &fx, &fy);
add(0, 3*m+1, abs(sx-fx)+abs(sy-fy));
for(i=1;i<=m;i++){
scanf("%d %d", &x[i], &y[i]);
a[i] = x[i], b[i] = y[i];
}
sort(a+1, a+1+m);
sort(b+1, b+1+m);
for(i=1;i<=m;i++){
add(0, i+m, abs(sx-a[i]));
add(0, i+2*m, abs(sy-b[i]));
if(i!=1){
add(i+m, i+m-1, abs(a[i]-a[i-1]));
add(i+2*m, i+2*m-1, abs(b[i]-b[i-1]));
}
if(i!=m){
add(i+m, i+m+1, abs(a[i]-a[i+1]));
add(i+2*m, i+2*m+1, abs(b[i]-b[i+1]));
}
}
for(i=1;i<=m;i++){
add(i, 3*m+1, abs(x[i]-fx)+abs(y[i]-fy));
int pos = lower_bound(a+1, a+1+m, x[i])-a;
add(i, pos+m, 0), add(pos+m, i, 0);
pos = lower_bound(b+1, b+1+m, y[i])-b;
add(i, pos+2*m, 0), add(pos+2*m, i, 0);
}
printf("%d\n", dijkstra(3*m+1));
return 0;
}
void add(int fr, int to, int w)
{
g[fr].push_back(node(to, w));
}
int dijkstra(int n)
{
for(int i=0;i<=n;i++)
dis[i] = 2e9;
dis[0] = 0;
priority_queue<P,vector<P>, greater<P> > que;
que.push(P(dis[0], 0));
while(!que.empty())
{
P p = que.top();que.pop();
int u = p.second, v, w;
if(p.first > dis[u])continue;
for(int i=0;i<g[u].size();i++){
v = g[u][i].to, w = g[u][i].w;
if(dis[v] > dis[u]+w){
dis[v] = dis[u]+w;
que.push(P(dis[v], v));
}
}
}
return dis[n];
}
相關文章
- POJ2387 Til the Cows Come Home【最短路 Dijkstra演算法】演算法
- 【原創】MySQL 返回更新值(RETURNING)MySql
- 動態 SQL、EXECUTE IMMEDIATE、using、into、returningSQL
- Recipe 1.10. Returning n Random Recordsrandom
- oracle 動態語句中的returning用法Oracle
- 次短路
- Small Multiple(最短路)
- JavaScript短路表示式JavaScript
- KunlunDB功能之insert/update/delete...returning語句delete
- Oracle Forum HOMEOracle
- 2024_4_22 路徑花費為最長$k$條邊之和最短路
- Laravel7.0 Route::get ()->name ('home') route ('home') 報錯Laravel
- [vue-router] Duplicate named routes definition: { name: "home", path: "/home" }Vue
- HDFS短路讀詳解
- 克隆(clone) ORACLE HOMEOracle
- Clone (克隆) ORACLE HOMEOracle
- 圖論 最短路總結圖論
- 矩陣求最短路徑矩陣
- Floyd最短路演算法演算法
- 最短路徑演算法演算法
- spark_home的配置Spark
- mac set $java_homeMacJava
- 最短路徑(Floyd演算法)演算法
- Djikstra最短路徑演算法演算法
- 最短路dijkstra演算法演算法
- POJ 2240 Arbitrage(Floyd最短路)
- GI PSU滾動方式應用GI HOME和DB HOME(opatch auto together)
- 如何找到JAVA_HOME | BaeldungJava
- clone grid INfrastructure Home and clusterwareASTStruct
- oracle clone oracle_home 方法Oracle
- 最短路徑(Dijskra演算法)JS演算法
- 最短路徑演算法總結演算法
- 最短路演算法的總結演算法
- js短路運算簡單介紹JS
- 最短路徑之Floyd演算法演算法
- 演算法:最短路徑問題演算法
- HDU3665Seaside(最短路徑)IDE
- Oracle 12C RAC的單機Standby returning error ORA-16191OracleError