zoj 1232(Floyd預處理 + 狀態圖上的最短路(好題))

題目鏈接

思想挺好的一個題目, 跟這個題做法類似, 但要多一步預處理, 詳見代碼。。。


#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_pair

queue<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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章