题意:求s到t走过边数大于k的最短路
思路:邻接表实现,用w[u][e]来维护(看的大牛博客),u表示当前点,e表示已经经过多少条边。感觉有点类似DP。
在边数大于k的处理上,发现还是使之等于k(K<=50),节省存储空间。
spfa算法实现。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #include<climits> 11 #include<string.h> 12 #include<cmath> 13 #include<stdlib.h> 14 #include<vector> 15 #define INF 1000000007 16 #define MAXN 5010 17 #define maxn 1000010 18 #define Mod 1000007 19 #define N 1010 20 using namespace std; 21 typedef long long LL; 22 23 struct node{ 24 int u, e; 25 }; 26 int n, m, u, v, wt; 27 int s, t, k; 28 int ans; 29 int dist[MAXN][55]; 30 bool inq[MAXN][55]; 31 vector< pair<int, int> > G[MAXN]; 32 33 void spfa(int s) 34 { 35 int u, v, e, i, j, len; 36 for (i = 0; i <= n; ++i) 37 for (j = 0; j <= 50; ++j) { 38 dist[i][j] = INF; 39 inq[i][j] = 0; 40 } 41 queue<node> q; 42 ans = INF; 43 dist[s][0] = 0; 44 inq[s][0] = true; 45 q.push({s,0}); 46 while (!q.empty()) { 47 node tmp = q.front(); 48 q.pop(); 49 u = tmp.u; 50 e = tmp.e; 51 if (u == t && e == k) 52 ans = min(dist[u][e],ans); 53 inq[u][e] = false; 54 int time; 55 if (e + 1 > k) time = k; 56 else time = e + 1; 57 for (i = 0; i < G[u].size(); ++i) { 58 v = G[u][i].first; 59 len = G[u][i].second; 60 if (dist[v][time] > len + dist[u][e]) { 61 dist[v][time] = len + dist[u][e]; 62 if (!inq[v][time]) { 63 q.push({ v, time }); 64 inq[v][time] = true; 65 } 66 } 67 } 68 } 69 } 70 71 int main() 72 { 73 while (cin >> n >> m) { 74 for (int i = 0; i < MAXN; ++i) G[i].clear(); 75 for (int i = 0; i < m; ++i) { 76 cin >> u >> v >> wt; 77 G[u].push_back({ v, wt }); 78 G[v].push_back({ u, wt }); 79 } 80 cin >> s >> t >> k; 81 spfa(s); 82 if (ans == INF) puts("-1"); 83 else cout << ans << endl; 84 } 85 return 0; 86 }
时间: 2024-10-25 01:58:03