• poj 3259


    SPFA加邻接矩阵勉强过了

      1 #include <iostream>
      2 #include <string>
      3 #include <vector>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <map>
      7 #include <algorithm>
      8 #include <list>
      9 #include <ctime>
     10 #include <set>
     11 #include <string.h>
     12 #include <queue>
     13 #include <cstdio>
     14 using namespace std;
     15 typedef int typep;
     16 int maxData = 500000;
     17 #define N 505
     18 #define CLR(arr, what) memset(arr, what, sizeof(arr))
     19 int path[N][N];
     20 int d[N];
     21 int n;
     22 //double maxData = 0;
     23 
     24 bool relax(typep u, typep& v, typep w) {
     25     if (v > (u + w)) {
     26         v = u + w;
     27         return true;
     28     } else
     29         return false;
     30 }
     31 
     32 bool bellman_ford(int s) {
     33     //int n = d.size();
     34     int i, j, k;
     35     bool judge;
     36 
     37     for (i = 0; i < n - 1; i++) {
     38         for (j = 0; j < n; j++) {
     39             for (k = 0; k < n; k++) {
     40                 if (path[j][k] != maxData && d[j] != maxData)
     41                     judge = relax(d[j], d[k], path[j][k]);
     42             }
     43         }
     44     }
     45 
     46     for (j = 0; j < n; j++) {
     47         for (k = 0; k < n; k++) {
     48             if (path[j][k] != maxData && d[j] != maxData) {
     49                 judge = relax(d[j], d[k], path[j][k]);
     50                 if (judge) {
     51                     return true;
     52                 }
     53             }
     54 
     55         }
     56     }
     57 
     58     return false;
     59 }
     60 
     61 
     62 int cnt[N];//记录顶点入队列次数
     63 bool final[N];//记录顶点是否在队列中,SPFA算法可以入队列多次
     64 bool SPFA(int s) {
     65     queue<int> myqueue;
     66     int i;
     67     CLR(final,0);
     68     CLR(cnt,0);
     69     final[s] = true;
     70     cnt[s]++; //源点的入队列次数增加
     71     myqueue.push(s);
     72     int topint;
     73     bool judge;
     74     while (!myqueue.empty()) {
     75         topint = myqueue.front();
     76         myqueue.pop();
     77         final[topint] = false;
     78         for (i = 0; i < n; ++i) {
     79             if (d[topint] < maxData) {
     80                 judge = relax(d[topint], d[i], path[topint][i]);
     81                 if (judge) {
     82                     if (!final[i]) { //判断是否在当前的队列中
     83                         final[i] = true;
     84                         cnt[i]++;
     85                         if (cnt[i] >= n) //当一个点入队的次数>=n时就证明出现了负环。
     86                             return true;
     87                         myqueue.push(i);
     88                     }
     89                 }
     90             }
     91         }
     92     }
     93     return false;
     94 }
     95 
     96 int main() {
     97     int f, m, w, u, v, c, t;
     98     cin >> f;
     99     for (int abc = 0; abc < f; abc++) {
    100         scanf("%d%d%d", &t, &m, &w);
    101         n = t + 1;
    102         CLR(path, maxData);
    103         for (int i = 0; i < t; i++) {
    104             path[0][i + 1] = 0;
    105         }
    106         for (int i = 0; i < m; i++) {
    107             scanf("%d %d %d", &u, &v, &c);
    108             path[u][v] = min(path[u][v], c);
    109             path[v][u] = min(path[v][u], c);
    110         }
    111         for (int i = 0; i < w; i++) {
    112             scanf("%d %d %d", &u, &v, &c);
    113             path[u][v] = min(path[u][v], 0 - c);
    114         }
    115         int judge = false;
    116         CLR(d, maxData);
    117         d[0] = 0;
    118         //judge = bellman_ford(0);
    119         judge = SPFA(0);
    120         if (judge) {
    121             cout << "YES" << endl;
    122         } else {
    123             cout << "NO" << endl;
    124         }
    125     }
    126     return 0;
    127 }

    对于这种稀疏矩阵,邻接表的方法更快,附代码

    #include <iostream>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cmath>
    #include <map>
    #include <algorithm>
    #include <list>
    #include <ctime>
    #include <set>
    #include <string.h>
    #include <queue>
    #include <cstdio>
    using namespace std;
    typedef int typep;
    const int E = 10000;
    const int V = 600;
    #define typec int                       // type of cost
    const typec inf = 1000000; // max of cost
    int n, m, pre[V], edge[E][3];
    typec dist[V];
    int relax(typec u, typec v, typec c) {
        if (dist[v] > dist[u] + c) {
            pre[v] = u;
            dist[v] = dist[u] + c;
            return 1;
        }
        return 0;
    }
    int bellman(int src) {
        int i, j;
        for (i = 0; i < n; ++i) {
            dist[i] = inf;
            pre[i] = -1;
        }
        dist[src] = 0;
        bool flag;
        for (i = 1; i < n; ++i) {
            flag = false; //  优化
            for (j = 0; j < m; ++j) {
                if (1 == relax(edge[j][0], edge[j][1], edge[j][2]))
                    flag = true;
            }
            if (!flag)
                break;
        }
        for (j = 0; j < m; ++j) {
            if (1 == relax(edge[j][0], edge[j][1], edge[j][2]))
                return 0; //  有负圈
        }
        return 1;
    }
    inline void addedge(int u, int v, typec c) {
        edge[m][0] = u;
        edge[m][1] = v;
        edge[m][2] = c;
        m++;
    }
    int main() {
        int f, mt, w, u, v, c, t;
        cin >> f;
        for (int abc = 0; abc < f; abc++) {
            scanf("%d%d%d", &t, &mt, &w);
            n = t + 1;
            m = 0;
            for (int i = 0; i < t; i++) {
                addedge(0, i + 1, 0);
            }
            for (int i = 0; i < mt; i++) {
                scanf("%d %d %d", &u, &v, &c);
                addedge(u, v, c);
                addedge(v, u, c);
            }
            for (int i = 0; i < w; i++) {
                scanf("%d %d %d", &u, &v, &c);
                addedge(u, v, -c);
            }
            int judge = false;
            judge = bellman(0);
            if (!judge) {
                cout << "YES" << endl;
            } else {
                cout << "NO" << endl;
            }
        }
        return 0;
    }

    from kakamilan

  • 相关阅读:
    从视频中每隔固定帧进行提取图片
    np.concatenate的超简单理解
    python-OOP(面向对象)
    机器学习中的ground truth
    深度学习网络中backbone是什么意思?
    缓存
    Linux基础命令
    openoffice相关命令
    HTTP协议
    Solr基础
  • 原文地址:https://www.cnblogs.com/kakamilan/p/3075889.html
Copyright © 2020-2023  润新知