zoukankan      html  css  js  c++  java
  • 浅谈spfa几个优化

    优化一:每次更新节点时,记录当前走的这条路径的节点数,当节点数大于n时,有负环,退出。注意,这里与常规的节点被更新n次以上退出不一样,效率比常规高。

    优化二:双端队列SLF优化。当当前节点到起点距离小于队首的时候,将此点插入队首,否则,正常插入队尾。可能咋一看感觉这种优化可能被用到的机会很少,但很可能正好解决掉了专门卡spfa的数据以及网格图。

    优化三:与优化二类似,但改为小于队列元素平均数时加入队首,还没试过。

    附上一道用spfa但以上优化效果很明显的一道题

    http://codeforces.com/gym/101498/problem/L

    不加优化2500ms左右(TLE边缘),加入优化一和优化二后311ms。

      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pii pair<int, int>
     27 #define pb push_back
     28 #define mp make_pair
     29 #define clr(a, x) memset(a, x, sizeof(a))
     30 
     31 const double pi = acos(-1.0);
     32 const int INF = 0x3f3f3f3f;
     33 const int MOD = 1e9 + 7;
     34 const double EPS = 1e-9;
     35 
     36 /*
     37 #include <ext/pb_ds/assoc_container.hpp>
     38 #include <ext/pb_ds/tree_policy.hpp>
     39 
     40 using namespace __gnu_pbds;
     41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
     42 */
     43 
     44 int T, n, m, u, v, c;
     45 map<pii, int> mmp;
     46 struct edge {
     47     int v, c;
     48     edge () {}
     49     edge (int v, int c) : v(v), c(c) {}
     50     bool operator < (const edge &e) const {
     51         return c < e.c;}
     52 };
     53 vector<edge> E[2015];
     54 ll spfa(int &flag) {
     55     bool in_que[2015];
     56     ll dis[2015];
     57     int cnt[2015];
     58 
     59     clr(in_que, 0);
     60     clr(cnt, 0);
     61     for (int i = 1; i <= n; ++i) {
     62         dis[i] = 1e18;
     63     }
     64     dis[0] = 0;
     65     deque<int> que;
     66     que.push_front(0);
     67 
     68     while (que.size()) {
     69         int x = que.front(); que.pop_front();
     70         in_que[x] = 0;
     71         for (int i = 0; i < E[x].size(); ++i) {
     72             int v = E[x][i].v, c = E[x][i].c;
     73             if (dis[v] > dis[x] + c) {
     74                 dis[v] = dis[x] + c;
     75                 if (!in_que[v]) {
     76                     if (que.size() && dis[v] < dis[que.front()] + 1) {
     77                         que.push_front(v);
     78                     } else {
     79                         que.push_back(v);
     80                     }
     81                     in_que[v] = 1;
     82                     cnt[v] = cnt[x] + 1;
     83                     if (n < cnt[v]) {
     84                         flag = 1;
     85                         return 2333;
     86                     }
     87                 }
     88             }
     89         }
     90     }
     91 
     92     ll ans = 1e18;
     93     for (int i = 1; i <= n; ++i) {
     94         ans = min(ans, dis[i]);
     95     }
     96     return ans;
     97 }
     98 int main() {
     99     scanf("%d", &T);
    100     while (T--) {
    101         scanf("%d%d", &n, &m);
    102         mmp.clear();
    103         int mi = 1e18;
    104         for (int i = 1; i <= m; ++i) {
    105             scanf("%d%d%d", &u, &v, &c);
    106             if (mmp.count(pii(u, v))) {
    107                 int x = mmp[pii(u, v)];
    108                 c = min(x, c);
    109             }
    110             mmp[pii(u, v)] = c;
    111             mi = min(mi, c);
    112         }
    113         if (mi >= 0) {
    114             printf("%d
    ", mi);
    115             continue;
    116         }
    117         for (int i = 1; i <= n; ++i) E[i].clear();
    118         for (map<pii, int>::iterator it = mmp.begin(); it != mmp.end(); ++it) {
    119             int u = (*it).first.first, v = (*it).first.second, c = (*it).second;
    120             E[u].pb(edge(v, c));
    121         }
    122         for (int i = 1; i <= n; ++i) {
    123             E[0].pb(edge(i, 0));
    124         }
    125         for (int i = 0; i <= n; ++i) {
    126             sort(E[i].begin(), E[i].end());
    127         }
    128         int flag = 0;
    129         ll ans = spfa(flag);
    130         if (flag) {
    131             puts("-inf");
    132         } else {
    133             printf("%lld
    ", ans);
    134         }
    135     }
    136     return 0;
    137 }
    View Code
  • 相关阅读:
    定时日志清理
    python ros 订阅robot_pose获取机器人位置
    python ros 重新设置机器人的位置
    c 宏的定义
    dos与unix系统的格式转化
    robot_pose的类型
    ROS编译时(catkin_make)找不到bullet,Could NOT find Bullet (missing: BULLET_DYNAMICS_LIBRARY
    python 压缩tar 包
    python 文件分割
    python 千位分隔符,
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8776497.html
Copyright © 2011-2022 走看看