題意 :
- 如上題easy version,求出最少的朋友數量,使得只有這些朋友在迷宮中時,無論vlad如何走,都能抓住vlad
思路 :
- 同樣先求出所有朋友到達其他點的最短路,在vlad的bfs中,如果到達這個點比某個朋友慢,就累積一個朋友
- 這個算法中不存在某個朋友被累加多次的可能。因為在距離 vlad 最近的那個被抓住的點上,bfs不會往下擴展,而是向其他子結點拓展,此時這個朋友一定比 vlad 慢,否則這個點就不是距離 1 號點(vlad出發點)最近的點了。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_set>
#include <math.h>
using namespace std
;typedef long long ll
;
typedef pair
<int, int> PII
;#define endl '\n'
#define fi first
#define se second
#define push_back
#define rep(i, l, r) for (ll i = l; i <= r; i ++ )const int N
= 2e5 + 10, M
= N
* 2, inf
= 0x3f3f3f3f;int n
, k
;
int h
[N
], ne
[M
], e
[M
], idx
;
int q
[N
];
int dist
[N
];
bool st
[N
];
PII mq
[N
]; void add(int a
, int b
)
{e
[idx
] = b
, ne
[idx
] = h
[a
], h
[a
] = idx
++ ;
}void solve()
{cin
>> n
>> k
;idx
= 0;for (int i
= 1; i
<= n
; i
++ ) h
[i
] = -1, dist
[i
] = inf
, st
[i
] = false;int hh
= 0, tt
= -1;for (int i
= 1, x
; i
<= k
&& cin
>> x
; i
++ ){q
[ ++ tt
] = x
;st
[x
] = true;dist
[x
] = 0;}for (int i
= 1, u
, v
; i
<= n
- 1 && cin
>> u
>> v
; i
++ ) add(u
, v
), add(v
, u
);while (hh
<= tt
){int t
= q
[hh
++ ];for (int i
= h
[t
]; ~i
; i
= ne
[i
]){int j
= e
[i
];if (!st
[j
]) dist
[j
] = dist
[t
] + 1, q
[ ++ tt
] = j
, st
[j
] = true;}}for (int i
= 1; i
<= n
; i
++ ) st
[i
] = false;hh
= 0, tt
= 0;mq
[0] = {1, 0};st
[1] = true;int cnt
= 0;while (hh
<= tt
){auto t
= mq
[hh
++ ];int r
= t
.fi
, d
= t
.se
;if (d
>= dist
[r
]) {cnt
++ ; continue; }if (ne
[h
[r
]] == -1 && r
!= 1 && d
< dist
[r
]) return cout
<< "-1\n", void();for (int i
= h
[r
]; ~i
; i
= ne
[i
]){int j
= e
[i
];if (!st
[j
]) mq
[ ++ tt
] = {j
, d
+ 1}, st
[j
] = true; }}cout
<< cnt
<< endl
;
}int main()
{cin
.tie(nullptr) -> sync_with_stdio(false);int _
;cin
>> _
;while (_
-- )solve();return 0;
}
總結
以上是生活随笔為你收集整理的Escape The Maze (hard version) 多源最短路,bfs(1900)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。