牛客練習賽14 E-無向圖中的最短距離(bfs+bitset)
阿新 • • 發佈:2019-02-20
連結:https://www.nowcoder.com/acm/contest/82/E
來源:牛客網
,yi)
來源:牛客網
題目描述
有一個n個點的無向圖,有m次查詢,每次查詢給出一些(xi,yi)
令dist(x,y)表示x和y點在圖中最短距離,dist(x,x)=0,如果x,y不連通則dist(x,y) = inf
每次查詢圖中有多少個點v與至少一個這次詢問給出的(xi,yi)滿足dist(v,xi)<=yi
輸入描述:
第一行三個數表示n,m,q
之後m行每行兩個數x,y表示有一條x與y之間的邊,邊權為1
之後q次詢問,每個詢問先給你一個數a
之後一行2a個數,第2i-1個數xi和第2i個數yi表示一個二元組(xi輸出描述:
輸出q行,每行一個數表示這次詢問的答案
題解: 開始在想為什麼邊的長度都為1,如邊的長度隨意的話只是求個多源最短路時間就超了, 但是由於邊長都為1,可以直接bfs求出最短路。 列舉每一個出發到所有點的最短路,可以在1000*100000的時間內求得。 0<=x,y<=1000,一共有1000000種組合,可以先打個表,用bitset儲存 然後2100000*1000/64的時間內求出答案。 #include<bits/stdc++.h> using namespace std; const int maxn = 1002; bitset<maxn>bit[maxn][maxn]; int d[maxn][maxn], n; bool is[maxn]; vector<int>p[maxn]; queue<int>P; void bfs(int id) { memset(is, 0, sizeof(is)); is[id] = 1; d[id][id] = 0; P.push(id); while (!P.empty()) { int v = P.front(); P.pop(); int L = p[v].size(); for (int i = 0; i<L; i++) { int to = p[v][i]; if (!is[to]) { is[to] = 1; P.push(to); d[id][to] = d[id][v] + 1; } } } } int main() { int m, Q; scanf("%d%d%d", &n, &m, &Q); for (int i = 0; i<m; i++) { int x, y; scanf("%d%d", &x, &y); p[x].push_back(y); p[y].push_back(x); } memset(d, -1, sizeof(d)); for (int i = 1; i <= n; i++) { bfs(i); for (int j = 0; j <= n; j++) if(d[i][j]!=-1)bit[i][d[i][j]][j] = 1; for (int j = 1; j <= n; j++)bit[i][j] |= bit[i][j - 1]; } while (Q--) { int T; scanf("%d", &T); bitset<maxn>ans; while (T--) { int x, y; scanf("%d%d", &x, &y); ans |= bit[x][y]; } printf("%d\n", ans.count()); } return 0; }