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 }