Recently, I have encountered this Floyd Warshall problem, that the problem adds extra constraint on the shortest path (all edge weights + 1 largest vertice on the path). Following my understanding, Floyd Warshall is dynamic programming and when we "relax" the state, I will add that extra condition.
So, I call dp[i][j][k]: the min distance between i and j vertices, and the middle vertices consisting only the first k vertices. And maxCost[i][j][k] is the max cost vertice of the path I have chosen in dp[i][j][k]. So my transition:
if (dp[i][j][k] + maxCost[i][j][k] > dp[i][k][k — 1] + dp[k][j][k — 1] + max(maxCost[i][k][k — 1], maxCost[k][j][k — 1]) or if the last chosen path for two vertices i and j has larger cost for the path for i, j and k is in the middle of the path, then I relax distance between i and j, and set new maxCost for that path. But there is problem with this logic can you help to point it out. Thank!
Codeint n, r, q;
const int mxn = 85;
int dp[mxn][mxn][mxn];
int cost[mxn];
int maxCost[mxn][mxn][mxn];
int test = 1;
void solve() {
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= n; k++) {
dp[i][j][k] = IINF;
maxCost[i][j][k] = -1;
}
}
}
for (int i = 1; i <= n; i++) cin >> cost[i];
for (int i = 1; i <= n; i++) {
dp[i][i][0] = 0;
maxCost[i][i][0] = cost[i];
}
for (int i = 0; i < r; i++) {
int u, v, w; cin >> u >> v >> w;
int newMaxCost = max(maxCost[u][u][0], maxCost[v][v][0]);
if (dp[u][v][0] + maxCost[u][v][0] > w + newMaxCost) {
dp[u][v][0] = dp[v][u][0] = w;
maxCost[u][v][0] = maxCost[v][u][0] = newMaxCost;
}
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (dp[i][j][k - 1] != IINF) {
if (dp[i][j][k] + maxCost[i][j][k] > dp[i][j][k - 1] + maxCost[i][j][k - 1]) {
dp[i][j][k] = dp[i][j][k - 1];
maxCost[i][j][k] = maxCost[i][j][k - 1];
}
}
if (dp[i][k][k - 1] != IINF && dp[k][j][k - 1] != IINF) {
int newMaxCost = max(maxCost[i][k][k - 1], maxCost[k][j][k - 1]);
if (dp[i][j][k] + maxCost[i][j][k] > dp[i][k][k - 1] + dp[k][j][k - 1] + newMaxCost) {
dp[i][j][k] = dp[i][k][k - 1] + dp[k][j][k - 1];
maxCost[i][j][k] = newMaxCost;
}
}
}
}
}
cout << "Case #" << test++ << nline;
for (int m = 0; m < q; m++) {
int u, v; cin >> u >> v;
if (dp[u][v][n] != IINF) cout << dp[u][v][n] + maxCost[u][v][n] << nline;
else cout << -1 << nline;
}
cout << nline;
}
Consider this test case:
Your code prints
10021, but I think the correct answer is10003. If I understand your logic correctly, here is your problem: you calculatedp[4][3][3]to be 20 (and not 2): even though $$$4 \to 2 \to 3$$$ has edges summing to only 2, the feast at 2 would cost 1000, meanwhile by going $$$4 \to 1 \to 3$$$ you pay 20 for the edges but 100 for the feast. Here's why this breaks: once you include 5, the feast will be held there and it turns out that going $$$4 \to 2 \to 3$$$ would have been cheaper after all.Use normal Floyd-Warshall (without all that
maxCoststuff), but in the outermost loop, don't go from $$$k = 1$$$ to $$$n$$$, instead go in the increasing order of the cost of holding the feast in city $$$k$$$. When queried about cities $$$u$$$ and $$$v$$$, take the minimum over allkofdp[u][v][k] + max(cost[u], cost[v], cost[k]).Thank you so much for pointing it out, I have understood why my logic failed. But during debug this kind of problem, it took me so much time and still did not know where the logic failed. So, another question.. How do you come up with the test case.
Experience I guess. After reading what you said in the blog I quickly thought "but what if you choose a more expensive path because it has a cheaper feast, and then it turns out you won't use that feast anyway". Then I just constructed a test case to prove that this can happen.
What you also can do is:
Red coders will always say it is just practice but, in reality, it is $$$IQ$$$ and practice is just a way to express the $$$IQ$$$. Imagine $$$IQ$$$ is like how tall you are and codeforces is like basketball. No amount of practice can make a $$$5'0$$$ guy have the same skill as a $$$8'0$$$ guy.
I think your mindset is the problem
But let me ask you this: if it were $$$100$$$% practice, then why'd he add this in?
It seems to me like he just thought of it and had no idea how the thought came about. My thought is: if it were experience, surely he'd see that his thought came from something he did in his past experience (and so he would have said "experience" more confidently in his comment). But maybe I am wrong.