题目抽象:给出nz个点组成的连通图,给出每个点的连接顶点。给出nr条路径。要求找出某点,使得到达每条路径上的每个顶点的距离的最大值最小。
分析:以每条路径上的顶点为起点,bfs搜索。具体见代码。
1 /******************************** 2 please don‘t hack me!! /(ToT)/~~ 3 __------__ 4 /~ ~ 5 | //^\\//^\| 6 /~~\ || T| |T|:~ 7 | |6 ||___|_|_||:| 8 \__. / o \/‘ 9 | ( O ) 10 /~~~~\ `\ \ / 11 | |~~\ | ) ~------~` 12 /‘ | | | / ____ /~~~) 13 (_/‘ | | | /‘ | ( | 14 | | | \ / __)/ 15 \ \ \ \/ /‘ \ ` 16 \ \|\ / | |\___| 17 \ | \____/ | | 18 /^~> \ _/ < 19 | | \ 20 | | \ \ 21 -^-\ \ | ) 22 `\_______/^\______/ 23 ************************************/ 24 25 #include <iostream> 26 #include <cstdio> 27 #include <cstring> 28 #include <cmath> 29 #include <algorithm> 30 #include <string> 31 #include <vector> 32 #include <set> 33 #include <map> 34 #include <queue> 35 #include <stack> 36 #include <cstdlib> 37 #include <sstream> 38 using namespace std; 39 typedef long long LL; 40 const LL INF = 0x5fffffff; 41 const double EXP = 1E-8; 42 const LL MOD = (LL)1E9+7; 43 const int MS = 10000; 44 45 int nz, nr; 46 int cnt[MS]; 47 int edges[MS][11]; 48 int dis[MS]; 49 int reach[MS]; //可以bfs防止重复访问某节点,也可以判断是否存在标号为i的地区 50 int cur; //reach[i] == cur. 表示地区i在第cur+ 1站访问到。 51 52 void bfs(int x) { 53 int val = 1; // 层次 54 queue<int> que[2]; // 层次扩展的滚动队列 55 int a = 0, b = 1; 56 if (reach[x] < cur) { 57 reach[x] = cur; 58 que[b].push(x); 59 dis[x] = max(dis[x],val); 60 val++; 61 } 62 while (!que[b].empty()) { 63 swap(a,b); 64 while (!que[a].empty()) { 65 int u = que[a].front(); 66 que[a].pop(); 67 for (int i = 0; i < cnt[u]; i++) { 68 int v = edges[u][i]; 69 if (reach[v] < cur) { //如果在本站中访问了,那么reach[v] == cur. 70 reach[v] = cur; 71 dis[v] = max(dis[v],val); 72 que[b].push(v); 73 } 74 } 75 } 76 val++; 77 } 78 } 79 80 int main() { 81 int T; 82 scanf("%d",&T); 83 while (T--) { 84 scanf("%d%d",&nz,&nr); 85 int id,x; 86 for (int i = 0; i < nz; i++) { 87 scanf("%d",&id); 88 scanf("%d",&cnt[id]); 89 for (int j = 0; j < cnt[id]; j++) { 90 scanf("%d",&edges[id][j]); 91 } 92 } 93 memset(dis,0,sizeof(dis)); 94 memset(reach,-1,sizeof(reach)); 95 cur = 0; 96 for (int i = 0; i < nr; i++) { 97 int n; 98 scanf("%d",&n); 99 for (int j = 0; j < n; j++) { 100 scanf("%d",&x); 101 bfs(x); 102 cur++; 103 } 104 } 105 int minv = INF; 106 int center = 0; 107 for (int i = 0; i < MS; i++) { 108 //因为题目中并没有说编号是连续的,地区的编号可能是随意的。 109 //我们可以用reach[i] == cur -1 来判断是否存在编号为i的地区。 110 if (reach[i] == cur -1 && dis[i] < minv) { 111 minv = dis[i]; 112 center = i; 113 } 114 } 115 printf("%d %d\n",minv,center); 116 } 117 return 0; 118 }
时间: 2024-10-10 15:33:02