2016 Europe

来源:互联网 发布:软件测试的周期 编辑:程序博客网 时间:2024/05/30 22:47

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 tonwhich 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(1m < n), the number of cells containing iron ore, and k(1 k < n), the number of cellscontaining coal.

  • One line with mdistinct integers o1,...,om(1oinfor all 1im), whereo1,...,omarethe IDs of cells with iron ore.

  • One line with kdistinct integers c1,...,ck(1cinfor all 1ik), wherec1,...,ckare theIDs of cells with coal.

  • nlines describing the topology of the board. Thej-th line of this block speci es the accessibleneighbours of thej-th cell and consists of the following integers:

    One integer 0a10, the number of cells accessible from cellj.adistinctintegersb1,...,ba(1bin,bi̸=jforall1ia),theIDsofthecells

    accessible from cellj.
    It is guaranteed, that no cell contains both resources, iron ore and coal. At the beginning of the

    game 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 one

    cell with iron ore. Output ‘impossible’ if it is impossible to own both, coal and iron ore.

    Sample Input

    3 1 1

    2
    3

    1 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;    }}


原创粉丝点击