There is a person from a city to another city (Points <= 30) and then there are n horse tickets. If two neighboring cities go, one horse ticket will be consumed. The time spent is the speed value on the horse ticket. The Edge/rate is the time spent. The last question is how much time the person spends, and then the DP [S] [v] stands for the minimum time the ticket that consumes S sets has elapsed to reach v. transfer. It can also be transferred directly. The reason for direct transfer is that this figure consumes tickets because of the need to walk, so it is actually a DAG to read the two types of code
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> #define MAXN 2222 #define INF 1000000007 using namespace std; double dp[333][33]; typedef pair<int, int> P; vector<P>g[33]; int t, n, m, src, des; int num[33]; int main () { int u, v, w; while(scanf("%d%d%d%d%d", &t, &n, &m, &src, &des) != EOF) { if(!t && !n && !m && !src && !des) break; for(int i = 0; i < t; i++) scanf("%d", &num[i]); for(int i = 0; i <= n; i++) g[i].clear(); for(int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); g[u].push_back(make_pair(v, w)); g[v].push_back(make_pair(u, w)); } for(int i = 0; i <= 300; i++) for(int j = 0; j < 33; j++) dp[i][j] = INF; dp[0][src] = 0; double res = INF; for(int i = 0; i < (1 << t); i++) { for(u = 1; u <= n; u++) for(int k = 0; k < t; k++) if(!(i & (1 << k))) { for(int j = 0; j < g[u].size(); j++) { v = g[u][j].first; w = g[u][j].second; dp[i | (1 << k)][v] = min(dp[i | (1 << k)][v], dp[i][u] + (double)w / num[k]); } } res = min(res, dp[i][des]); } if(res == INF) puts("Impossible"); else printf("%.3f\n", res); } return 0; }
Then SPFA
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> #define MAXN 2222 #define INF 1000000007 using namespace std; double dp[333][33]; typedef pair<int, int> P; vector<P>g[33]; int t, n, m, src, des; int num[33], vis[333][33]; queue<P>q; void spfa() { for(int i = 0; i <= 300; i++) for(int j = 0; j < 33; j++) dp[i][j] = INF; memset(vis, 0, sizeof(vis)); dp[0][src] = 0; vis[0][src] = 1; while(!q.empty()) q.pop(); q.push(make_pair(0, src)); while(!q.empty()) { P top = q.front(); q.pop(); int S = top.first; int u = top.second; for(int j = 0; j < t; j++) { if(S & (1 << j)) continue; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i].first; int w = g[u][i].second; if(dp[S | (1 << j)][v] > dp[S][u] + (double)w / num[j]) { dp[S | (1 << j)][v] = dp[S][u] + (double)w / num[j]; if(!vis[S | (1 << j)][v]) { q.push(make_pair(S | (1 << j), v)); vis[S | (1 << j)][v] = 1; } } } } } double res = INF; for(int i = 0; i < (1 << t); i++) res = min(res, dp[i][des]); if(res == INF) puts("Impossible"); else printf("%.3f\n", res); } int main () { int u, v, w; while(scanf("%d%d%d%d%d", &t, &n, &m, &src, &des) != EOF) { if(!t && !n && !m && !src && !des) break; for(int i = 0; i < t; i++) scanf("%d", &num[i]); for(int i = 0; i <= n; i++) g[i].clear(); for(int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); g[u].push_back(make_pair(v, w)); g[v].push_back(make_pair(u, w)); } spfa(); } return 0; }