zoukankan      html  css  js  c++  java
  • [BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA & 拓扑排序)

    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 ≤ ≤ 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,输入数据保证没有重边和自环。

    Source

      Day2

    Solution

      补个条件:$mleq 500000$

      如果$dis_{s->u_i}+w_i=dis_{t->v_i}$,那么边$i$才可能成为答案

      这些边组成的图一定是一个拓扑图,走一遍最长链即可。

      其实主要的坑点在于因为是无向图,所以需要反着做一遍

      也就是说,$x_1$->$y_1$和$y_2$->$x_2$的公共路径也可能是答案,也就是说,原题意是错的= =b

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 struct edge
      4 {
      5     int v, w, nxt;
      6 }e[2000005];
      7 int fst[2][1505], dis[6][1505], q[2105], indeg[1505];
      8 int n, etot, sss1, ttt1, sss2, ttt2;
      9 bool inq[1505];
     10 
     11 void addedge(int *f, int u, int v, int w)
     12 {
     13     e[++etot] = (edge){v, w, f[u]}, f[u] = etot;
     14 }
     15 
     16 bool check(int u, int i)
     17 {
     18     if(dis[1][u] + e[i].w + dis[2][e[i].v] != dis[1][ttt1]) return false;
     19     return dis[3][u] + e[i].w + dis[4][e[i].v] == dis[3][ttt2];
     20 }
     21 
     22 void SPFA(int sss, int *d)
     23 {
     24     int front = 0, back;
     25     memset(d, 63, 6020);
     26     q[back = 1] = sss, d[sss] = 0, inq[sss] = true;
     27     while(front != back)
     28     {
     29         int u = q[++front & 2047];
     30         front &= 2047, inq[u] = false;
     31         for(int i = fst[0][u]; i; i = e[i].nxt)
     32             if(d[e[i].v] > d[u] + e[i].w)
     33             {
     34                 d[e[i].v] = d[u] + e[i].w;
     35                 if(!inq[e[i].v])
     36                 {
     37                     q[++back & 2047] = e[i].v;
     38                     back &= 2047, inq[e[i].v] = true;
     39                 }
     40             }
     41     }
     42 }
     43 
     44 int Topo_sort()
     45 {
     46     int front = 0, back = 0, ans = 0;
     47     for(int i = 1; i <= n; ++i)
     48         if(!indeg[i]) q[++back] = i;
     49     while(front != back)
     50     {
     51         int u = q[++front];
     52         for(int i = fst[1][u]; i; i = e[i].nxt)
     53         {
     54             int v = e[i].v, w = e[i].w;
     55             dis[0][v] = max(dis[0][v], dis[0][u] + w);
     56             if(!--indeg[e[i].v]) q[++back] = v;
     57         }
     58     }
     59     for(int i = 1; i <= n; ++i)
     60         ans = max(ans, dis[0][i]);
     61     return ans;
     62 }
     63 
     64 int main()
     65 {
     66     int m, u, v, w, ans;
     67     scanf("%d%d", &n, &m);
     68     scanf("%d%d%d%d", &sss1, &ttt1, &sss2, &ttt2);
     69     for(int i = 1; i <= m; ++i)
     70     {
     71         scanf("%d%d%d", &u, &v, &w);
     72         addedge(fst[0], u, v, w);
     73         addedge(fst[0], v, u, w);
     74     }
     75     SPFA(sss1, dis[1]), SPFA(ttt1, dis[2]);
     76     SPFA(sss2, dis[3]), SPFA(ttt2, dis[4]);
     77     for(int i = 1; i <= n; ++i)
     78         for(int j = fst[0][i]; j; j = e[j].nxt)
     79             if(check(i, j))
     80             {
     81                 addedge(fst[1], i, e[j].v, e[j].w);
     82                 ++indeg[e[j].v];
     83             }
     84     ans = Topo_sort();
     85     memset(fst[1], 0, sizeof(fst[1]));
     86     memset(dis[0], 0, sizeof(dis[0]));
     87     memset(indeg, 0, sizeof(indeg));
     88     swap(sss2, ttt2);
     89     SPFA(sss2, dis[3]), SPFA(ttt2, dis[4]);
     90     for(int i = 1; i <= n; ++i)
     91         for(int j = fst[0][i]; j; j = e[j].nxt)
     92             if(check(i, j))
     93             {
     94                 addedge(fst[1], i, e[j].v, e[j].w);
     95                 ++indeg[e[j].v];
     96             }
     97     ans = max(ans, Topo_sort());
     98     printf("%d
    ", ans);
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    【Selenium IDE】下载安装Chrome和Firefox插件IDE ide了解就行 不是重点 重点是写脚本
    调用接口时,生产环境,路径加斜杠“/”和不加的区别
    WPF 踩坑笔记12 DataGrid触发选中行事件
    WPF 踩坑笔记11 线程取消
    WPF 踩坑笔记10 ListBox异步动态加载
    WPF 踩坑笔记9 直接打印
    思维的体操
    【洛谷 P4213】 【模板】杜教筛(Sum)
    【洛谷 P2257】 YY的GCD(莫比乌斯反演)
    【洛谷 P4980】 【模板】Pólya 定理
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5618932.html
Copyright © 2011-2022 走看看