• P2149 [SDOI2009]Elaxia的路线


    P2149 [SDOI2009]Elaxia的路线

    提交 6.45k
    通过 1.87k
    时间限制 1.00s
    内存限制 125.00MB
    题目提供者 xmyzwls
    历史分数100

    提交记录

    查看算法标签
    进入讨论版

    相关讨论

     
    查看讨论

    推荐题目

     
    查看推荐
     

    展开

    题目描述

    最近,Elaxia 和 w** 的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们必须合理地安排两个人在一起的时间。

    Elaxia 和 w** 每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。

    现在已知的是 Elaxia 和 w** 所在的宿舍和实验室的编号以及学校的地图:
    地图上有 nnn 个路口,mmm 条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

    输入格式

    第一行两个正整数 n,mn,mn,m,表示点数和边数。

    第二行四个正整数 x1,y1,x2,y2x_1,y_1,x_2,y_2x1,y1,x2,y2,分别表示 Elaxia 的宿舍和实验室及 w** 的宿舍和实验室的标号。

    接下来 mmm 行,每行三个整数 u,v,wu,v,wu,v,w,表示 u,vu,vu,v之间有一条边,需要 www 的时间经过。

    输出格式

    一行一个整数表示答案。(即最长公共路径的长度)

    输入输出样例

    输入 #1
    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
    输出 #1
    3

    思路

      这道题一开始拿到的思路是给最短路全打上标记,但是发现一个坑,这里交了只有10分,就是标记的方向问题。

      后来想了想可以把标记问题转换一下。

      假设 x1 -> y1 上存在一点对 (u, v) ,且 uv 间有路,若 dis[x1][u] + dis[u][v] + dis[v][y1] == dis[x1][y1] 则说明 uv 一定是一组被标记的带方向的最短路上一个点对。

      我们跑四次dijkstra处理出 x1->y1, x2->y2, y1->x1, y2->x2的dis,之后枚举所有的边,找到所有的形似uv这样被标记的点对,通过四次拓扑排序建立DAG图,在DAG图上找最长链即可。

      因为要跑多次拓扑和dijkstra,初始化是很重要的。

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 template<class T>inline void read(T &res)
     10 {
     11     char c;T flag=1;
     12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     14 }
     15 
     16 namespace _buff {
     17     const size_t BUFF = 1 << 19;
     18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     19     char getc() {
     20         if (ib == ie) {
     21             ib = ibuf;
     22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     23         }
     24         return ib == ie ? -1 : *ib++;
     25     }
     26 }
     27 
     28 int qread() {
     29     using namespace _buff;
     30     int ret = 0;
     31     bool pos = true;
     32     char c = getc();
     33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     34         assert(~c);
     35     }
     36     if (c == '-') {
     37         pos = false;
     38         c = getc();
     39     }
     40     for (; c >= '0' && c <= '9'; c = getc()) {
     41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     42     }
     43     return pos ? ret : -ret;
     44 }
     45 
     46 const int maxn = 2e5 + 7;
     47 const int inf  = 0x3f3f3f3f;
     48 
     49 int head[maxn << 2], edge[maxn << 2], w[maxn << 2], nxt[maxn << 2];
     50 int cnt;
     51 
     52 inline void BuildGraph (int u, int v, int c) {
     53     cnt++;
     54     edge[cnt] = v;
     55     nxt[cnt]  = head[u];
     56     w[cnt] = c;
     57     head[u] = cnt;
     58 }
     59 
     60 struct node {
     61     int u,v;
     62     bool operator <(const node &t) const {
     63         return u > t.u;
     64     }
     65 };
     66 
     67 struct Node {
     68     int v, w;
     69 };
     70 
     71 int n,m,s,t;
     72 int dis[10][maxn];
     73 bool vis[maxn];
     74 int minn = 0;
     75 
     76 vector <Node> e[maxn];
     77 queue<Node> que;
     78 
     79 priority_queue < node > q;
     80 
     81 void dijkstra(int s, int id) {
     82     memset(vis, 0, sizeof(vis));
     83     for(int i = 1; i <= n; i++) {
     84         dis[id][i] = 0x3f3f3f3f;
     85     }
     86     dis[id][s] = 0;
     87     q.push({0,s});
     88     while(!q.empty()) {
     89         node temp = q.top();
     90         q.pop();
     91         if(vis[temp.v]) continue;
     92         vis[temp.v] = true;
     93         for(int i = head[temp.v]; i; i = nxt[i]) {
     94             int v = edge[i];
     95             int c = w[i];
     96             if(dis[id][v] > dis[id][temp.v] + c) {
     97                 dis[id][v] = dis[id][temp.v] + c;
     98                 q.push({dis[id][v],v});
     99             }
    100         }
    101     }
    102 }
    103 
    104 int in[maxn];
    105 int ddis[maxn];
    106 int ans;
    107 
    108 void topo(int s1, int s2, int s3, int s4, int x1, int y1, int x2, int y2) {
    109     for ( int i = 1; i <= n; ++i ) {
    110         e[i].clear();
    111     }
    112     memset(in, -1, sizeof(in));
    113     for ( int i = 1; i <= n; ++i ) {
    114         for (int j = head[i]; j; j = nxt[j]) {
    115             int u = i;
    116             int v = edge[j];
    117             int c = w[j];
    118             //printf("dis[%d][%d]:%d c:%d dis[%d][%d]:%d dis[%d][%d]:%d
    ",s1,u,dis[s1][u],c,s2,v,dis[s2][v],s1,y1,dis[s1][y1]);
    119             if(dis[s1][u] + c + dis[s2][v] == dis[s1][y1]) {
    120                 if(dis[s3][u] + c + dis[s4][v] == dis[s3][y2]) {
    121                     if(in[u] == -1)
    122                         in[u]=0;
    123                     if(in[v] == -1)
    124                         in[v]=0;
    125                     in[v]++;
    126                     e[u].push_back({v,c});
    127                 }
    128             }
    129         }
    130     }
    131     while(!que.empty()) {
    132         que.pop();
    133     }
    134     for ( int i = 1; i <= n; ++i ) {
    135         if(in[i] == 0) {
    136             Node temp;
    137             temp.v = i, temp.w = 0;
    138             que.push(temp);
    139         }
    140     }
    141     memset(ddis, 0, sizeof(ddis));
    142     while(!que.empty()) {
    143         Node temp;
    144         temp = que.front();
    145         que.pop();
    146         int u = temp.v;
    147         for ( int i = 0; i < e[u].size(); ++i ) {
    148             int v = e[u][i].v;
    149             int c = e[u][i].w;
    150             if(in[v] == -1) continue;
    151             ddis[v] = max(ddis[v], ddis[u] + c);
    152             //printf("ddis[%d]:%d
    ",v, ddis[v]);
    153             ans = max(ans, ddis[v]);
    154             in[v]--;
    155             if(in[v] == 0) {
    156                 que.push(e[u][i]);
    157             }
    158         }
    159     }
    160 }
    161 
    162 int main()
    163 {
    164     scanf("%d %d",&n, &m);
    165     int x1, y1, x2, y2;
    166     scanf("%d %d %d %d",&x1, &y1, &x2, &y2);
    167     
    168     int a, b, c;
    169     for (int i = 1; i <= m; ++i) {
    170         scanf("%d %d %d",&a, &b, &c);
    171         BuildGraph(a, b, c);
    172         BuildGraph(b, a, c);
    173     }
    174     dijkstra(x1, 1);
    175     dijkstra(y1, 2);
    176     dijkstra(x2, 3);
    177     dijkstra(y2, 4);
    178     ans = 0;
    179     topo(1,2,3,4,x1,y1,x2,y2);
    180     topo(1,2,4,3,x1,y1,y2,x2);
    181     topo(2,1,3,4,y1,x1,x2,y2);
    182     topo(2,1,4,3,y1,x1,y2,x2);
    183     cout << ans << endl;
    184     return 0;
    185 }
    View Code
  • 相关阅读:
    python 打包模块:nuitka
    模型量化
    .Net Core 起步
    adobe flash retired forever
    时间格式(全)
    Python使用chorm对ClickHouse简单查询及写入
    利用iFFT还原的图片有毛刺
    本人Linux常用命令
    Exp8 web综合
    Git 分支管理规范
  • 原文地址:https://www.cnblogs.com/orangeko/p/12358694.html
Copyright © 2020-2023  润新知