典型的BFS。
基本思路:从每条线路上的每个地区z出发进行BFS遍历;对每个地区j,如果地区j是最终求得的中心地区,则要保证从它出发能到达每条路上每个地区z,并且选择的星形阈值要尽可能的小,因此统计每个地区z到地区j最短距离中的最大值,这个最大值记录在数组元素step[j]中;最后求得的最小的星形阈值就是每个地区j的step[j]的最小值,中心地区就是取得最小值的地区j。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define MAXN 10000
#define INF 1000000
using namespace std;
int step[MAXN+5];
int ans[MAXN+5];
int area[10005][12];
bool used[MAXN+5];
bool vis[MAXN+5];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(area,-1,sizeof(area));
int nz,nr;
scanf("%d%d",&nz,&nr);
for(int i=0; i<nz; ++i)
{
int _id;
scanf("%d",&_id);
scanf("%d",&area[_id][0]);
for(int j=1; j<=area[_id][0]; ++j)
scanf("%d",&area[_id][j]);
}
memset(ans,0x80,sizeof(ans));
memset(used,0,sizeof(used));
for(int i=0; i<nr; ++i)
{
int n;
scanf("%d",&n);
for(int ii=0; ii<n; ++ii)
{
int tmp;
scanf("%d",&tmp);
if(used[tmp]) continue;
else used[tmp]=true;
queue<int> q;
memset(step,0,sizeof(step));
memset(vis,0,sizeof(vis));
q.push(tmp);
vis[tmp]=true;
while(!q.empty())
{
int t=q.front();
q.pop();
for(int j=1; j<=area[t][0]; ++j)
if(!vis[area[t][j]])
{
step[area[t][j]]=step[t]+1;
vis[area[t][j]]=true;
q.push(area[t][j]);
}
}
for(int j=1; j<=MAXN; ++j)
if(area[j][0]!=-1)
ans[j]=max(ans[j],step[j]);
}
}
int res=INF,pos;
for(int i=1; i<=MAXN; ++i)
if(area[i][0]!=-1)
{
if(ans[i]<res)
{
res=ans[i];
pos=i;
}
}
printf("%d %d\n",res+1,pos);
}
return 0;
}