zoukankan      html  css  js  c++  java
  • [SDOI 2009]Elaxia的路线

    Description

    最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

    Input

    第一行:两个整数N和M(含义如题目描述)。 第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ y2 ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。 接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。 出出出格格格式式式::: 一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)。

    Output

    一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

    Sample Input

    9 10
    1 6 7 8
    1 2 1
    2 5 2
    2 3 3
    3 4 2
    3 9 5
    4 5 3
    4 6 4
    4 7 2
    5 8 1
    7 9 1

    Sample Output

    3

    HINT

    对于30%的数据,N ≤ 100;
    对于60%的数据,N ≤ 1000;
    对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。

    题解

    一开始看点数小,直接强行$SPFA$预处理出第一条路径,然后再$SPFA$第二条路径时记录答案。$TLE$...

    • 首先,分别从$x_1$,$y_1$,$x_2$,$y_2$为源点分别跑一次$SPFA$,记$dis[0][u]$,$dis[1][u]$,$dis[2][u]$,$dis[3][u]$分别为从$x_1$,$y_1$,$x_2$,$y_2$为起始点到点$u$的最短路径。

    • 构建出一个新的有向图,包含$x_1->y_1$和$x_2->y_2$的所有最短路上的边。判断一条边$u->v$是否在$x_1->y_1$的最短路上,就是判断$dis[1][u]+val(u,v)+dis[2][v]==dis[1][y1]$($val(u,v)$为边$u->v$的长度),如果为真,那么在最短路上,为假则不在最短路上。是否在$x_2->y_2$的最短路上同理。

    • 不过要注意一点,因为边的走向可能是$u->v$,也可能是$v->u$。所以,对于一条边必须判断两次(第一次为$u->v$,第二次为$v->u$)。

    • 最后,按照新图的拓扑序,在各个点之间进行递推,求得答案。
      1 //It is made by Awson on 2017.10.20
      2 #include <set>
      3 #include <map>
      4 #include <cmath>
      5 #include <ctime>
      6 #include <cmath>
      7 #include <stack>
      8 #include <queue>
      9 #include <vector>
     10 #include <string>
     11 #include <cstdio>
     12 #include <cstdlib>
     13 #include <cstring>
     14 #include <iostream>
     15 #include <algorithm>
     16 #define LL long long
     17 #define Min(a, b) ((a) < (b) ? (a) : (b))
     18 #define Max(a, b) ((a) > (b) ? (a) : (b))
     19 #define sqr(x) ((x)*(x))
     20 #define y1 yy
     21 using namespace std;
     22 const int N = 1500;
     23 
     24 int n, m, x1, x2, y1, y2, u, v, c;
     25 struct tt {
     26   int to, cost, next;
     27   bool color;
     28 }edge[(N*N>>1)+5], g[(N*N>>1)+5];
     29 int path[N+5], top, path_g[N+5], top_g;
     30 int dist[4][N+5], ans, cnt[N+5], in[N+5];
     31 struct node {
     32   int x, val;
     33   node (){
     34   }
     35   node (int _x, int _val) {
     36     x = _x, val = _val;
     37   }
     38 };
     39 
     40 void init(int u, int v, int c) {
     41   g[++top_g].to = v;
     42   g[top_g].cost = c;
     43   g[top_g].next = path_g[u];
     44   path_g[u] = top_g;
     45 }
     46 void add(int u, int v, int c) {
     47   edge[++top].to = v;
     48   edge[top].next = path[u];
     49   edge[top].cost = c;
     50   path[u] = top;
     51 }
     52 void topsort() {
     53   queue<node>Q; while (!Q.empty()) Q.pop();
     54   for (int i = 1; i <= n; i++) if (!in[i]) Q.push(node(i, 0));
     55   while (!Q.empty()) {
     56     int u = Q.front().x, val = Q.front().val; Q.pop();
     57     ans = Max(ans, val);
     58     for (int i = path_g[u]; i; i = g[i].next) {
     59       int v = g[i].to; in[v]--; cnt[v] = Max(cnt[v], val+g[i].cost);
     60       if (!in[v]) Q.push(node(v, cnt[v]));
     61     }
     62   }
     63 }
     64 void SPFA(int x, int t) {
     65   bool vis[N+5] = {0}; vis[x] = 1;
     66   memset(dist[t], 127/3, sizeof(dist[t])); dist[t][x] = 0;
     67   queue<int>Q; while (!Q.empty()) Q.pop(); Q.push(x);
     68   while (!Q.empty()) {
     69     int u = Q.front(); Q.pop(); vis[u] = 0;
     70     for (int i = path[u]; i; i = edge[i].next) {
     71       int v = edge[i].to;
     72       if (dist[t][v] > dist[t][u]+edge[i].cost) {
     73     dist[t][v] = dist[t][u]+edge[i].cost;
     74     if (!vis[v]) {
     75       vis[v] = 1; Q.push(v);
     76     }
     77       }
     78     }
     79   }
     80 }
     81 void work() {
     82   scanf("%d%d%d%d%d%d", &n, &m, &x1, &y1, &x2, &y2);
     83   for (int i = 1; i <= m; i++) {
     84     scanf("%d%d%d", &u, &v, &c);
     85     add(u, v, c), add(v, u, c);
     86   }
     87   SPFA(x1, 0); SPFA(y1, 1); SPFA(x2, 2), SPFA(y2, 3);
     88   for (int u = 1; u <= n; u++)
     89     for (int i = path[u]; i; i = edge[i].next) {
     90       int v = edge[i].to;
     91       if (dist[0][u]+dist[1][v]+edge[i].cost != dist[0][y1]) continue;
     92       if (dist[2][u]+dist[3][v]+edge[i].cost != dist[2][y2]) continue;
     93       init(u, v, edge[i].cost); in[v]++;
     94     }
     95   topsort();
     96   memset(path_g, 0, sizeof(path_g)); top_g = 0;
     97   memset(cnt, 0, sizeof(cnt));
     98   for (int u = 1; u <= n; u++)
     99     for (int i = path[u]; i; i = edge[i].next) {
    100       int v = edge[i].to;
    101       if (dist[1][u]+dist[0][v]+edge[i].cost != dist[0][y1]) continue;
    102       if (dist[2][u]+dist[3][v]+edge[i].cost != dist[2][y2]) continue;
    103       init(u, v, edge[i].cost); in[v]++;
    104     }
    105   topsort();
    106   printf("%d
    ", ans);
    107 }
    108 int main() {
    109   work();
    110   return 0;
    111 }
  • 相关阅读:
    HTML 笔记
    JavaScript 学习笔记
    对近期的一些总结
    【 Java 】手速手速~
    【 Java 】 简易交通灯
    【 Art 】小心心~
    scala 标识符案例
    scala 基础类型
    scala 类、字段、方法
    scala 列表
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7700621.html
Copyright © 2011-2022 走看看