• POJ-3268 Silver Cow Party---正向+反向Dijkstra


    题目链接:

    https://vjudge.net/problem/POJ-3268

    题目大意:

    有编号为1-N的牛,它们之间存在一些单向的路径。给定一头牛的编号X,其他牛要去拜访它并且拜访完之后要返回自己原来的位置,求所有牛从开始到回家的时间是多少?

    思路:

    所有牛都回到了家所花费的时间就是这些牛中花费时间的最大者,可以正向的Dijkstra求出从X到每个点的最短时间,然后一个骚操作:将所有边反向(swap(Map[i][j], Map[j][i])),再从x用dijkstra求出X到每个点的最短时间,第二次求出来的时间通过逆向求出来的是每个点到X的最短时间,两个一加,取最大者就是答案。

    本题也可以用Bellman来求,不过由于边比较多,必须用队列优化的SPFA来求,但是SPA需要邻接表,不能像邻接矩阵那样直接反向,所以存图的时候存两张图,一张正向,一张反向,跑俩遍出结果。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<map>
     9 #include<set>
    10 #include<sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn = 1000 + 10;
    14 const int INF = 1e9 + 7;
    15 int T, n, m, cases;
    16 int Map[maxn][maxn];
    17 int d1[maxn], d2[maxn];
    18 bool v[maxn];
    19 void flip()
    20 {
    21     for(int i = 1; i <= n; i++)
    22     {
    23         for(int j = i + 1; j <= n; j++)swap(Map[i][j], Map[j][i]);
    24     }
    25 }
    26 void dijkstra(int u, int d[])
    27 {
    28     memset(v, 0, sizeof(v));
    29     for(int i = 0; i <= n; i++)d[i] = INF;
    30     d[u] = 0;
    31     for(int i = 1; i <= n; i++)
    32     {
    33         int x, m = INF;
    34         for(int i = 1; i <= n; i++)if(!v[i] && d[i] <= m)m = d[x = i];//找距离源点最近的点
    35         v[x] = 1;
    36         for(int i = 1; i <= n; i++)d[i] = min(d[i], d[x] + Map[x][i]);//进行松弛
    37     }
    38 }
    39 int main()
    40 {
    41     int u, x, y, z;
    42     while(cin >> n >> m >> u)
    43     {
    44         for(int i = 0; i <= n; i++)
    45             for(int j = 0; j <= n; j++)Map[i][j] = (i == j ? 0 : INF);
    46         for(int i = 0; i < m; i++)
    47         {
    48             scanf("%d%d%d", &x, &y, &z);
    49             //cout<<"000"<<endl;
    50             Map[x][y] = z;
    51         }
    52         dijkstra(u, d1);
    53         flip();
    54         dijkstra(u, d2);
    55         for(int i = 1; i <= n; i++)d1[i] += d2[i];
    56         sort(d1 + 1, d1 + n + 1);
    57         cout<<d1[n]<<endl;
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    test20190805 夏令营NOIP训练20
    test20190803 夏令营NOIP训练19
    test20190802 夏令营NOIP训练18
    「SDOI2016」征途
    LG4195 【模板】exBSGS
    test20190731 夏令营NOIP训练16
    CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths
    CF623E Transforming Sequence
    LG4351 [CERC2015]Frightful Formula
    CF553E Kyoya and Train
  • 原文地址:https://www.cnblogs.com/fzl194/p/8732687.html
Copyright © 2020-2023  润新知