Bus Pass ZOJ 2913 BFS 最大中取最小的
/*该题的解题思路为BFS,从某点开始进行BFS,以层数表示到该地区的距离,用到了滚动队列。
对每个公交车的站点进行BFS,记录每个地区到该公交站的距离,遍历完后会得出每个地区到
所有公交站点的最大距离,以此知道选择了该地区后的星型阀值。然后从所有地区中选择一个
最小的*/
View Code
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #define ZMAX 10000 //地区编号的最大值 5 #define INF 100000 6 using namespace std; 7 int nz,nr; //地区的数目,公交路线的数目 8 int mz[ZMAX]; //mz[i] 为与第i个地区相邻的地区数目 9 //"邻接矩阵",edge[i][j]表示为编号为i的地区的第j个相邻地区的编号 10 int edge[ZMAX][10]; 11 int res[ZMAX]; //res[i] 表示每条路线上每个地区编号为i个地区距离中的最大值 12 int cur; //记录当前公交的站点次序,cur == 0表示当前是第0站 13 int reach[ZMAX]; //reach[s] == cur 表示地区s在第cur站已访问 14 15 int max(int x,int y) 16 { 17 return (x>y) ? x : y; 18 } 19 //从位置s出发进行BFS遍历(遍历其他所有顶点) 20 void BFS(int s) 21 { 22 int i ,a,b; 23 int val,at; //val用于记录层数,即距离; 24 //at用于表示BFS过程中的当前结点 25 queue<int> q[2]; 26 a = 0; 27 b =1; 28 val = 0; 29 if(reach[s] < cur) 30 { 31 q[b].push(s); 32 reach[s] = cur; 33 res[s] = max(res[s],val+1); 34 } 35 while(!q[b].empty()) 36 { 37 swap(a,b); //滚动队列 38 val++; 39 while(!q[a].empty()) //处理所有当前层结点 40 { 41 at = q[a].front(); 42 q[a].pop(); 43 for(i = 0; i < mz[at]; i++) 44 { 45 int d = edge[at][i]; 46 if(reach[d] < cur) 47 { 48 q[b].push(d); 49 reach[d] = cur; 50 res[d] = max(res[d],val+1); 51 } 52 } 53 } 54 } 55 } 56 int main() 57 { 58 int T; //输入文件中测试数据个数 59 int i,j;//循环变量 60 int id; //地区编号 61 int mr; //每条公交线路途径的地区数目 62 int ret,center;//最小星型阀值和取得最小星型阀值的中心地区编号 63 // freopen("in.cpp","r",stdin); 64 scanf("%d",&T); 65 while(T--) 66 { 67 memset(reach,-1,sizeof(reach)); 68 memset(res,0,sizeof(res)); 69 cur = 0; 70 scanf("%d%d",&nz,&nr); 71 for(i=0; i<nz; i++) 72 { 73 scanf("%d",&id); 74 scanf("%d",&mz[id]); 75 for(j = 0; j < mz[id]; j ++) 76 scanf("%d",&edge[id][j]); 77 } 78 for(i = 0; i < nr; i++) 79 { 80 scanf("%d",&mr); 81 for(j = 0; j < mr; j++) 82 { 83 scanf("%d",&id); 84 BFS(id); 85 cur++; 86 } 87 } 88 ret = INF; 89 for(i=0; i < 10000; i++) 90 { 91 if(reach[i] == cur-1 && res[i] < ret) 92 { 93 ret = res[i]; 94 center = i; 95 } 96 } 97 printf("%d %d\n",ret,center); 98 } 99 return 0; 100 }