zoukankan      html  css  js  c++  java
  • poj 1062

    有条件的最短路径算法,穷举可行的等级即可。

      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 int lvl, lvr;
     24 int costc[N];
     25 int costlv[N];
     26 
     27 bool check(int lv) {
     28     return (lvl <= lv && lv <= lvr);
     29 }
     30 
     31 bool relax(typep u, typep& v, typep w, typep lv1, typep lv2) {
     32     if (v > (u + w) && check(lv1) && check(lv2)) {
     33         v = u + w;
     34         return true;
     35     } else
     36         return false;
     37 }
     38 
     39 int cnt[N]; //记录顶点入队列次数
     40 bool final[N]; //记录顶点是否在队列中,SPFA算法可以入队列多次
     41 bool SPFA(int s) {
     42     queue<int> myqueue;
     43     int i;
     44     CLR(final, 0);
     45     CLR(cnt, 0);
     46     final[s] = true;
     47     cnt[s]++; //源点的入队列次数增加
     48     myqueue.push(s);
     49     int topint;
     50     bool judge;
     51     while (!myqueue.empty()) {
     52         topint = myqueue.front();
     53         myqueue.pop();
     54         final[topint] = false;
     55         for (i = 0; i < n; ++i) {
     56             if (d[topint] < maxData) {
     57                 judge = relax(d[topint], d[i], path[topint][i], costlv[topint], costlv[i]);
     58                 if (judge) {
     59                     if (!final[i]) { //判断是否在当前的队列中
     60                         final[i] = true;
     61                         cnt[i]++;
     62                         if (cnt[i] >= n) //当一个点入队的次数>=n时就证明出现了负环。
     63                             return true;
     64                         myqueue.push(i);
     65                     }
     66                 }
     67             }
     68         }
     69     }
     70     return false;
     71 }
     72 
     73 
     74 int main() {
     75     int degree, num, cp, cl, cx, rpob, rpmo;
     76     cin >> degree >> num;
     77     n = num;
     78     bool judge;
     79     CLR(path, maxData);
     80     for (int abc = 0; abc < num; abc++) {
     81         scanf("%d%d%d", &cp, &cl, &cx);
     82         costc[abc] = cp;
     83         costlv[abc] = cl;
     84         for (int i = 0; i < cx; i++) {
     85             scanf("%d%d", &rpob, &rpmo);
     86             rpob--;
     87             path[abc][rpob] = rpmo;
     88         }
     89     }
     90     int res = maxData;
     91     for (int i = costlv[0] - degree; i < costlv[0] + 1; i++) {
     92         lvl = i;
     93         lvr = i + degree;
     94         CLR(d, maxData);
     95         d[0] = 0;
     96         judge = SPFA(0);
     97         for (int i = 0; i < n; i++) {
     98             res = min(res, d[i] + costc[i]);
     99         }
    100     }
    101     cout << res;
    102     return 0;
    103 }

    邻接表的依旧更快一些

      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 #define N 505
     17 #define CLR(arr, what) memset(arr, what, sizeof(arr))
     18 //double maxData = 0;
     19 int lvl, lvr;
     20 int costc[N];
     21 int costlv[N];
     22 
     23 bool check(int lv) {
     24     return (lvl <= lv && lv <= lvr);
     25 }
     26 
     27 bool relax(typep u, typep& v, typep w, typep lv1, typep lv2) {
     28     if (v > (u + w) && check(lv1) && check(lv2)) {
     29         v = u + w;
     30         return true;
     31     } else
     32         return false;
     33 }
     34 
     35 typedef int typep;
     36 const int E = 10000;
     37 const int V = 100;
     38 #define typec int                       // type of cost
     39 const typec inf = 10000000; // max of cost
     40 int n, m, pre[V], edge[E][3];
     41 typec dist[V];
     42 int bellman(int src) {
     43     int i, j;
     44     for (i = 0; i < n; ++i) {
     45         dist[i] = inf;
     46         pre[i] = -1;
     47     }
     48     dist[src] = 0;
     49     bool flag;
     50     for (i = 1; i < n; ++i) {
     51         flag = false; //  优化
     52         for (j = 0; j < m; ++j) {
     53             if (1
     54                     == relax(dist[edge[j][0]], dist[edge[j][1]], edge[j][2],
     55                             costlv[edge[j][0]], costlv[edge[j][1]]))
     56                 flag = true;
     57         }
     58         if (!flag)
     59             break;
     60     }
     61     for (j = 0; j < m; ++j) {
     62         if (1
     63                 == relax(dist[edge[j][0]], dist[edge[j][1]], edge[j][2],
     64                         costlv[edge[j][0]], costlv[edge[j][1]]))
     65             return 0; //  有负圈
     66     }
     67     return 1;
     68 }
     69 inline void addedge(int u, int v, typec c) {
     70     edge[m][0] = u;
     71     edge[m][1] = v;
     72     edge[m][2] = c;
     73     m++;
     74 }
     75 
     76 int main() {
     77     int degree, num, cp, cl, cx, rpob, rpmo;
     78     cin >> degree >> num;
     79     n = num;
     80     bool judge;
     81     for (int abc = 0; abc < num; abc++) {
     82         scanf("%d%d%d", &cp, &cl, &cx);
     83         costc[abc] = cp;
     84         costlv[abc] = cl;
     85         for (int i = 0; i < cx; i++) {
     86             scanf("%d%d", &rpob, &rpmo);
     87             rpob--;
     88             addedge(abc, rpob, rpmo);
     89         }
     90     }
     91     int res = inf;
     92     for (int i = costlv[0] - degree; i < costlv[0] + 1; i++) {
     93         lvl = i;
     94         lvr = i + degree;
     95         judge = bellman(0);
     96         for (int i = 0; i < n; i++) {
     97             res = min(res, dist[i] + costc[i]);
     98         }
     99     }
    100     cout << res;
    101     return 0;
    102 }

    from kakamilan

  • 相关阅读:
    HDU 5135(再思考)
    HDU 5105
    HDU 5135
    Codeforces 985E
    Codeforces 985D
    Codeforces 975D
    Codeforces 975C
    Codeforces 976D
    HDU 1024 Max Sum Plus Plus (DP,水题)
    HDU 1003 Max Sum(DP,水题)
  • 原文地址:https://www.cnblogs.com/kakamilan/p/3079690.html
Copyright © 2011-2022 走看看