There are many excellent strategy board games, and yourfavourite among them is called “Steel Age”. It o ers manydi erent paths to victory but you prefer the blood-and- re-strategy: build as many soldiers as possible and club youropposition into submission. To be able to build soldiers youneed two resources: iron ore and coal.
The board consists of di erent cells numbered from 1 to nwhich can contain resources. The rules for moving from onecell to another are rather complicated: if you can move fromcell A to cell B, it does not always mean that you can alsomove from B to A. For example, if two cells are connectedby a river, then you may be able to move downstream, butnot upstream, so long as you didn’t invent a steam engine;however, it still could be possible to reach the upstream cellby using roads and taking a detour over other cells.
At the beginning of the game you own only one such cell, where all your settlers are located. Atevery move you are allowed to move an arbitrary number of settlers from a cell to one of its accessibleneighbours. By moving your settlers into a cell for the rst time, you “claim” it. Every claimed cellwill bind one settler, which has to stay in this cell until the end of the game. However, there is no needto leave a settler in your initial cell because it is where your palace is located and thus the cell staysclaimed for all time.
Your goal is to claim at least one cell containing the resource “iron ore” and at least one cell withresource “coal” in order to be able to build soldiers. What is the minimal number of settlers you needto reach this goal?
Input
The input le contains several test cases, each of them as described below.The input consists of:
-
One line with three integers n (2 ≤ n ≤ 105), the number of cells on the playing eld, m(1 ≤ m < n), the number of cells containing iron ore, and k (1 ≤ k < n), the number of cellscontaining coal.
-
One line with m distinct integers o1,...,om (1 ≤ oi ≤ n for all 1 ≤ i ≤ m), where o1,...,om arethe IDs of cells with iron ore.
-
One line with k distinct integers c1,...,ck (1 ≤ ci ≤ n for all 1 ≤ i ≤ k), where c1,...,ck are theIDs of cells with coal.
-
n lines describing the topology of the board. The j-th line of this block speci es the accessibleneighbours of the j-th cell and consists of the following integers:
– One integer 0 ≤ a ≤ 10, the number of cells accessible from cell j.–adistinctintegersb1,...,ba (1≤bi ≤n,bi ̸=jforall1≤i≤a),theIDsofthecells
accessible from cell j.
It is guaranteed, that no cell contains both resources, iron ore and coal. At the beginning of thegame you own only the cell with ID 1.
Output
For each test case, write on a line by itself, following the description below
Output the minimum number of settlers needed to claim at least one cell with coal and at least onecell with iron ore. Output ‘impossible’ if it is impossible to own both, coal and iron ore.
Sample Input
3 1 1
2
31 2
2 3 1
1 1
3 1 1
2
3
1 2
1 1
2 1 2
Sample Output
2
impossible
一个有向图,有一个队伍从1点出发找到碳跟铁,问走过的最短路是多少。
可以枚举所有点,求出点到这三个点的最短距离。
从1点的正常跑单源最短路就好了
因为碳跟铁是要求,各个点到该点的最短路,所以建立反向变求最短路
跑三遍最短路,然后枚举既可以了
#include <iostream> #include <algorithm> #include <stdio.h> #include <string.h> #include <queue> #include <vector> #include <utility> using namespace std; const int maxn = 200050; const long long INF = 0x3f3f3f3f; int n, m, k; int visited[maxn]; int head[maxn], total; int dis[maxn][3]; vector<int> state[3]; vector<int> edge1[maxn], edge2[maxn]; void init() { for (int i = 0; i < 3; ++i) { state[i].clear(); } for (int i = 0; i <= n; ++i) { edge1[i].clear(); edge2[i].clear(); } state[0] = {1}; memset(head, -1, sizeof(head)); total = 0; memset(dis, INF, sizeof(dis)); } template <int N> void bfs(int st, const vector<int>(&edge)[N]) { memset(visited, 0, sizeof(visited)); queue<int> que; for (int i = 0; i < state[st].size(); ++i) { int u = state[st][i]; visited[u] = 1; dis[u][st] = 0; que.push(u); } while (!que.empty()) { int u = que.front(); que.pop(); for (int i = 0; i < edge[u].size(); ++i) { int v = edge[u][i]; if (dis[v][st] > dis[u][st] + 1) { dis[v][st] = dis[u][st] + 1; if (!visited[v]) { visited[v] = 1; que.push(v); } } } visited[u] = 0; } } int main() { //freopen("in.txt", "r", stdin); ios::sync_with_stdio(false); while (cin >> n >> m >> k) { init(); for (int i = 0; i < m; ++i) { int a; cin >> a; state[1].push_back(a); } for (int i = 0; i < k; ++i) { int a; cin >> a; state[2].push_back(a); } for (int i = 1; i <= n; ++i) { int s; cin >> s; for (int j = 0; j < s; ++j) { int v; cin >> v; edge1[i].push_back(v); edge2[v].push_back(i); } } bfs(0, edge1); bfs(1, edge2); bfs(2, edge2); long long res = INF; for (int i = 1; i <= n; ++i) { //cout << dis[i][0] << " " << dis[i][1] << " " << dis[i][2] << endl; res = min(res, static_cast<long long>(dis[i][0]) + dis[i][1] + dis[i][2]); } if (res < INF) cout << res << endl; else cout << "impossible" << endl; } }