P2149 Elaxia的路线

D

e

s

c

r

i

p

t

i

o

n

\mathrm{Description}

Description

给定

n

n

n 个点,

m

m

m 条边的无向图,求

2

2

2 个点对间最短路的最长公共路径

S

o

l

u

t

i

o

n

\mathrm{Solution}

Solution

最短路有可能不唯一,所以公共路径的长度就有可能不同。

2

2

2 条最短路都会经过的边(包括同向和异向)记录出来,并建立

1

1

1 个新图,那么由于最短路(可以看做一条链)一定不会走环,故新图必定是一个 有向无环图 (简称

D

A

G

\mathrm{DAG}

DAG),而

D

A

G

\mathrm{DAG}

DAG 图上就可以跑 DP 来求解最长链,由于找出的是

2

2

2 条最短路都经过的边,所以最长链其实就是

2

2

2 条最短路的最长公共路径。

故,该问题得以解决。

C

o

d

e

Code

Code

#include

#define int long long

using namespace std;

typedef pair PII;

typedef long long LL;

const int SIZE = 1e6 + 10;

int N, M;

int X1, Y1, X2, Y2;

int h[SIZE], hs[SIZE], e[SIZE], ne[SIZE], w[SIZE], idx;

int D[4][SIZE], Vis[SIZE], in[SIZE], q[SIZE], hh, tt = -1;

int F[SIZE];

void add(int h[], int a, int b, int c)

{

e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;

}

void Dijkstra(int Start, int dist[])

{

for (int i = 1; i <= N; i ++)

dist[i] = 1e18, Vis[i] = 0;

priority_queue, greater> Heap;

Heap.push({0, Start}), dist[Start] = 0;

while (Heap.size())

{

auto Tmp = Heap.top();

Heap.pop();

int u = Tmp.second;

if (Vis[u]) continue;

Vis[u] = 1;

for (int i = h[u]; ~i; i = ne[i])

{

int j = e[i];

if (dist[j] > dist[u] + w[i])

{

dist[j] = dist[u] + w[i];

Heap.push({dist[j], j});

}

}

}

}

void Topsort()

{

hh = 0, tt = -1;

for (int i = 1; i <= N; i ++)

if (!in[i])

q[ ++ tt] = i;

while (hh <= tt)

{

int u = q[hh ++];

for (int i = hs[u]; ~i; i = ne[i])

{

int j = e[i];

if ((-- in[j]) == 0)

q[ ++ tt] = j;

}

}

}

signed main()

{

cin.tie(0);

cout.tie(0);

ios::sync_with_stdio(0);

memset(h, -1, sizeof h);

memset(hs, -1, sizeof hs);

cin >> N >> M >> X1 >> Y1 >> X2 >> Y2;

int u, v, c;

while (M --)

{

cin >> u >> v >> c;

add(h, u, v, c), add(h, v, u, c);

}

Dijkstra(X1, D[0]), Dijkstra(Y1, D[1]);

Dijkstra(X2, D[2]), Dijkstra(Y2, D[3]);

for (int i = 1; i <= N; i ++)

for (int j = h[i]; ~j; j = ne[j])

{

int k = e[j];

if (D[0][i] + w[j] + D[1][k] == D[0][Y1] && D[2][i] + w[j] + D[3][k] == D[2][Y2])

add(hs, i, k, w[j]), in[k] ++;

}

Topsort();

for (int it = 0; it <= tt; it ++)

{

int i = q[it];

for (int j = hs[i]; ~j; j = ne[j])

{

int k = e[j];

F[k] = max(F[k], F[i] + w[j]);

}

}

int Result = 0;

for (int i = 1; i <= N; i ++)

Result = max(Result, F[i]);

memset(hs, -1, sizeof hs);

memset(F, 0, sizeof F);

memset(in, 0, sizeof in);

for (int i = 1; i <= N; i ++)

for (int j = h[i]; ~j; j = ne[j])

{

int k = e[j];

if (D[0][i] + w[j] + D[1][k] == D[0][Y1] && D[3][i] + w[j] + D[2][k] == D[2][Y2])

add(hs, i, k, w[j]), in[k] ++;//, cout << i << " " << k << endl;

}

Topsort();

for (int it = 0; it <= tt; it ++)

{

int i = q[it];

for (int j = hs[i]; ~j; j = ne[j])

{

int k = e[j];

F[k] = max(F[k], F[i] + w[j]);

}

}

for (int i = 1; i <= N; i ++)

Result = max(Result, F[i]);

cout << Result << endl;

return 0;

}

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: