RT,代码:
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int N = 100005;
struct Edge {
int v, w, next;
} edge[8 * N];
int head[2 * N];
int cnt;
void add_edge(int u, int v, int w) {
cnt++;
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt;
}
int x[N], y[N], dis[2 * N];
vector < int > x_point[N], y_point[N];
bool cmpx(int u, int v) {
return x[u] > x[v];
}
bool cmpy(int u, int v) {
return y[u] > y[v];
}
struct Vertex {
int u, dis;
Vertex(int u_, int dis_) {
u = u_;
dis = dis_;
}
};
bool operator < (const Vertex & a, const Vertex & b) {
return a.dis > b.dis;
}
int min(int a, int b) {
return a < b ? a : b;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m + 2; i++) {
scanf("%d %d", &x[i], &y[i]);
x_point[x[i]].push_back(i);
y_point[y[i]].push_back(i);
}
for (int i = 1; i <= m; i++) {
add_edge(i, i + m + 2, 1);
add_edge(i + m + 2, i, 1);
}
add_edge(m + 1, 2 * m + 3, 0);
add_edge(2 * m + 3, m + 1, 0);
add_edge(m + 2, 2 * m + 4, 0);
add_edge(2 * m + 4, m + 2, 0);
for (int u, v, i = 1; i <= n; i++) {
sort(x_point[i].begin(), x_point[i].end(), cmpy);
for (int j = 0; j < (int)x_point[i].size() - 1; j++) {
u = x_point[i][j];
v = x_point[i][j + 1];
add_edge(u, v, 2 * (y[u] - y[v]));
add_edge(v, u, 2 * (y[u] - y[v]));
}
sort(y_point[i].begin(), y_point[i].end(), cmpx);
for (int j = 0; j < (int)y_point[i].size() - 1; j++) {
u = y_point[i][j];
v = y_point[i][j + 1];
add_edge(u + m + 2, v + m + 2, 2 * (x[u] - x[v]));
add_edge(v + m + 2, u + m + 2, 2 * (x[u] - x[v]));
}
}
for (int i = 1; i <= 2 * m + 4; i++) {
dis[i] = 0x7fffffff;
}
priority_queue < Vertex > q;
dis[m + 1] = 0;
q.push(Vertex(m + 1, 0));
while (!q.empty()) {
int u = q.top().u;
q.pop();
if (q.top().dis != dis[u]) {
continue;
}
for (int v, i = head[u]; i != 0; i = edge[i].next) {
v = edge[i].v;
if (dis[v] > dis[u] + edge[i].w) {
dis[v] = dis[u] + edge[i].w;
q.push(Vertex(v, dis[v]));
}
}
}
printf("%d", dis[m + 2]);
return 0;
}