nowcoder82E 无向图中的最短距离

题意:有一个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

题解:dp[i][j][k]代表i到k的距离是否小于等于j,这里三维存不下,用bitset差不多就是32*1000*1000*4B=128000000B=128M

每次可以dp[i][j] |= dp[i][j-1]就可以把低位的更新到高位上

#include <bits/stdc++.h>
#define maxn 1010
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
struct node{
    int d,u;
    bool operator<(const node& a) const{
        return d>a.d;
    }
};
bitset<maxn>b[maxn][maxn];
vector<int >G[maxn];
bool done[maxn];
int d[maxn][maxn], n, m, q;
void dfs(int st){
    for(int i=1;i<=n;i++) d[st][i] = n+1;
    memset(done, 0, sizeof(done));
    d[st][st] = 0;
    priority_queue<node>q;
    q.push((node){0, st});
    while(!q.empty()){
        node fi = q.top();q.pop();
        int u = fi.u;
        if(done[u]) continue;
        done[u] = 1;
        for(int i=0;i<G[u].size();i++){
            int x = G[u][i];
            if(1+d[st][u]<d[st][x]){
                d[st][x] = d[st][u]+1;
                q.push((node){d[st][x], x});
            }
        }
    }
}
int main(){
    int x, y, a;
    scanf("%d%d%d", &n, &m, &q);
    for(int i=1;i<=m;i++){
        scanf("%d%d", &x, &y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    for(int i=1;i<=n;i++){
        dfs(i);
        for(int j=1;j<=n;j++)
            b[i][d[i][j]][j] = 1;
        for(int j=1;j<=n;j++)
            b[i][j] |= b[i][j-1];
    }
    while(q--){
        scanf("%d", &a);
        bitset<maxn> ans;
        for(int i=0;i<a;i++){
            scanf("%d%d", &x, &y);
            ans |= b[x][y];
        }
        printf("%d
", ans.count());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/8697413.html