zoj 2913 Bus Pass

对于每个输入的站点求出所有点到这个站点的最短路。用anss数组存下来,然后就可以用anss数组求出答案了。

题目分析清楚了 还是比较水的,折腾了一早上。。

 

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<vector>

#include<queue>

#include<algorithm>

using namespace std;

struct Point{ int tott, node; };

vector<int> abc[11111];

int nz, nr, i, j, p, k, u, summ, ii;

int zhuan[11111];

int fan[11111];//

int anss[222][11111];//存最短路

int ff[11111];//标记这个城市有没有搜过最短路

void BFS(int rr)

{

    queue<Point>Q;  Point start, t;

    start.node = zhuan[k]; start.tott = 0; anss[rr][zhuan[k]] = 0; Q.push(start);

    while (!Q.empty())

    {

        Point hd = Q.front(); Q.pop();

        for (i = 0; i < abc[hd.node].size(); i++)

        {

            if (hd.tott + 1 < anss[rr][abc[hd.node][i]])

            {

                anss[rr][abc[hd.node][i]] = hd.tott + 1;

                t.node = abc[hd.node][i];

                t.tott = hd.tott + 1;

                Q.push(t);

            }

        }

    }

}

int main()

{

    int sb;scanf("%d", &sb);

    while (sb--)

    {

        scanf("%d%d", &nz, &nr);

        for (i = 0; i < 11105; i++) abc[i].clear();

        for (i = 0; i < 210; i++) for (j = 0; j < 11100; j++) anss[i][j] = 0x7FFFFFFF;

        memset(zhuan, 0, sizeof(zhuan));memset(ff, 0, sizeof(ff));

        int tot = 1, summ = 0;

        for (i = 1; i <= nz; i++)

        {

            scanf("%d", &p);

            if (zhuan[p] == 0) { zhuan[p] = tot, fan[zhuan[p]] = p, tot++; }

            scanf("%d", &k);

            for (j = 1; j <= k; j++)

            {

                scanf("%d", &u);

                if (zhuan[u] == 0) { zhuan[u] = tot, fan[zhuan[u]] = u, tot++; }

                abc[zhuan[p]].push_back(zhuan[u]);

            }

        }

        for (ii = 1; ii <= nr; ii++)

        {

            scanf("%d", &u);

            for (j = 1; j <= u; j++)

            {

                scanf("%d", &k);

                if (ff[k] == 0){ BFS(summ); ff[k] = 1; summ++; }

            }

        }

        int pri = 0x7FFFFFFF; int pri2 = -1;

        for (i = 1; i <= tot - 1; i++)

        {

            int minn = -1;

            for (j = 0; j < summ; j++) if (anss[j][i]>minn) minn = anss[j][i];

            if (minn < pri){ pri = minn, pri2 = fan[i]; }

            else if (minn == pri&&fan[i] < pri2)pri2 = fan[i];

        }

        printf("%d %d\n", pri + 1, pri2);

    }

    return 0;

}

 

你可能感兴趣的:(ZOJ)