zoj 1232(Floyd预处理 + 状态图上的最短路(好题))

来源:互联网 发布:有生日提醒软件 编辑:程序博客网 时间:2024/06/13 03:08

题目链接

思想挺好的一个题目, 跟这个题做法类似, 但要多一步预处理, 详见代码。。。


#include <vector>#include <queue>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;typedef pair<int, int> P;const int N = 105;const int INF = (int)1e9;#define BP cout << "here" << endl;#define fi first#define se second#define mp make_pairqueue<P> Q;int a, b, n, m, lim, K;int dp[N][15], dis[N][N];bool inq[N][15];void init() {for (int i = 0; i < n; i++) {fill(dis[i], dis[i] + n, INF);fill(dp[i], dp[i] + K + 1, INF);fill(inq[i], inq[i] + K + 1, 0);}}int main() {int test, u, v, w;scanf("%d", &test);while (test--) {scanf("%d%d%d%d%d", &a, &b, &m, &lim, &K);n = a + b;init();for (int i = 0; i < m; i++) {scanf("%d%d%d", &u, &v, &w);u--, v--;dis[u][v] = min(dis[u][v], w);dis[v][u] = dis[u][v];}for (int k = 0; k < a; k++)for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) {if (dis[i][k] + dis[k][j] > lim) continue;dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);}Q.push(mp(n - 1, 0));dp[n - 1][0] = 0;while (!Q.empty()) {P cur = Q.front(); Q.pop();int u = cur.fi;int t = cur.se;inq[u][t] = 0;for (int i = 0; i < n; i++) if (dis[u][i] != INF) {if (dp[i][t] > dp[u][t] + dis[u][i]) {dp[i][t] = dp[u][t] + dis[u][i];if (!inq[i][t]) {Q.push(mp(i, t));inq[i][t] = 1;}}if (t < K && dp[i][t + 1] > dp[u][t] && dis[u][i] <= lim) {dp[i][t + 1] = dp[u][t];if (!inq[i][t + 1]) {Q.push(mp(i, t + 1));inq[i][t + 1] = 1;}}}}int res = INF;for (int i = 0; i <= K; i++)res = min(res, dp[0][i]);printf("%d\n", res);}return 0;}