1、題面node
樣例輸入:spa
1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2code
樣例輸出:blog
3string
2、思路io
關鍵詞:分層BFS
class
考試時以爲題幹意思很清晰——求可將k條邊賦值爲0的最短路。起初幾個思路正確性均存疑,後來以爲應該要DP因而決定滯後了。。。im
正解——分層BFS,我的認爲思路與DP有些許相像,同時記錄節點及當前已賦值爲0的邊數,則在跑最短路時(這裏用的SPFA),可選擇是否將該條邊賦值爲0,當且僅當已選邊<k。next
3、代碼img
1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 100005 5 #define MAXM 200005 6 #define MAXK 15 7 #define INF 0x3f3f3f3f 8 9 int T, n, m, k, u, v, w, o, h[MAXN], d[MAXN][MAXK], vis[MAXN][MAXK]; 10 11 struct node { 12 int n, k; 13 } q[MAXN]; 14 15 struct edge { 16 int v, next, w; 17 } e[MAXM]; 18 19 void add(int u, int v, int w) { 20 o++, e[o] = (edge) {v, h[u], w}, h[u] = o; 21 } 22 23 int spfa() { 24 int head = 1, tail = 2; 25 memset(d, INF, sizeof(d)), memset(vis, 0, sizeof(vis)); 26 q[head] = (node) {1, 0}, d[1][0] = 0, vis[1][0] = 1; 27 while (head != tail) { 28 node o = q[head]; 29 vis[o.n][o.k] = 0; 30 for (int x = h[o.n]; x; x = e[x].next) { 31 int v = e[x].v; 32 if (d[v][o.k] > d[o.n][o.k] + e[x].w) { 33 d[v][o.k] = d[o.n][o.k] + e[x].w; 34 if (!vis[v][o.k]) vis[v][o.k] = 1, q[tail++] = (node) {v, o.k}; 35 } 36 if (o.k < k) { 37 if (d[v][o.k + 1] > d[o.n][o.k]) { 38 d[v][o.k + 1] = d[o.n][o.k]; 39 if (!vis[v][o.k + 1]) vis[v][o.k + 1] = 1, q[tail++] = (node) {v, o.k + 1}; 40 } 41 } 42 } 43 head++; 44 } 45 return d[n][k]; 46 } 47 48 int main() { 49 scanf("%d", &T); 50 for (int i = 1; i <= T; i++) { 51 o = 0, memset(h, 0, sizeof(h)); 52 scanf("%d %d %d", &n, &m, &k); 53 for (int j = 1; j <= m; j++) scanf("%d %d %d", &u, &v, &w), add(u, v, w); 54 printf("%d\n", spfa()); 55 } 56 return 0; 57 }
多個子問題着重考慮各類初始化!