• 牛客练习赛14 E


    一个链接:https://ac.nowcoder.com/acm/contest/82/E
    来源:牛客网

    无向图中的最短距离
    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    有一个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,yi

    输出描述:

    输出q行,每行一个数表示这次询问的答案
    示例1

    输入

    复制
    5 6 6
    2 3 
    1 3 
    2 5 
    1 3 
    3 2 
    2 5
    1
    3 1
    1
    1 1
    1
    1 4
    1
    5 2
    1
    1 4
    2
    1 0 5 1

    输出

    复制
    3
    2
    4
    3
    4
    3

    备注:

    对于100%的数据,n <= 1000 , m <= 100000 , q <=
    100000
    a的和<= 2100000

    题意:
    给你一个有向图,然后q个询问,每一个询问给你num个对数x,y 。
    问你在图中有多少个节点与这num对个数中的至少一对中的x的距离小于等于y。

    思路:
    首先对于每一个节点进行bfs找到它对其他节点的最短路。
    用数组 dis[i][j] 来维护 i到j的距离,
    那么我们定理一个 bitset<1011> bs[1011][1011]
    bs[i][j][k] 代表 第i个节点距离小于等于j的有没有k,有没有只有两个状态,即0/1
    所以用 bitset可以完美维护。
    对于处理,
    我们对每一个节点bfs后,更新 bs

    repd(j,1,n)
    {
      bs[i][dis[i][j]][j]=1;
    }

    又因为是 小于等于, 所以 bs[i][j][k] =1的话, 那么bs[i][j~n][k] 都为1.
    这样我们就可以从1到n,用bitset 的或运算|=来更新使距离j更大的一定包含更小的情况。

    然后对于询问,
    我们只需要让一个全是0的bitset 去|= 那num个 bs[x][y] 即可。
    最后得到的bitset中的1的个数就是答案数。

    细节见代码:
    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
    inline void getInt(int* p);
    const int maxn = 1010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    int dis[maxn][maxn];
    bitset<maxn> bs[maxn][maxn];
    int m;
    int q;
    bitset<maxn> res;
    std::vector<int> G[maxn];
    void bfs(int x)
    {
        dis[x][x] = 0;
        queue<int> q;
        q.push(x);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (auto y : G[u])
            {
                if (~dis[x][y])continue;
                dis[x][y] = dis[x][u] + 1;
                q.push(y);
            }
        }
    }
    int main()
    {
        // freopen("D:\common_text\code_stream\in.txt","r",stdin);
        // freopen("D:\common_text\code_stream\out.txt","w",stdout);
        memset(dis, -1, sizeof(dis));
        gbtb;
        cin >> n >> m >> q;
        int x, y;
        repd(t, 1, m)
        {
            cin >> x >> y;
            G[x].push_back(y);
            G[y].push_back(x);
        }
        repd(i, 1, n)
        {
            bfs(i);
            repd(j, 1, n)
            {
                bs[i][dis[i][j]][j] = 1;
            }
            repd(j, 1, n)
            {
                bs[i][j] |= bs[i][j - 1];
            }
        }
        int num;
        repd(t, 1, q)
        {
            cin >> num;
            res.reset();
            repd(i, 1, num)
            {
                cin >> x >> y;
                res |= bs[x][y];
            }
            cout << res.count() << endl;
        }
    
    
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
     
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    函数(方法
    变量
    常量
    文档注释与多行注释的区别
    标识符
    [置顶] WebService学习总结(3)——使用java JDK开发WebService
    WebService学习总结(2)——WebService是什么?
    [置顶] WebService学习总结(1)——WebService相关概念
    [置顶] WebService学习总结(1)——WebService相关概念
    Java基础学习总结(38)——Lombok的使用和原理
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10961225.html
Copyright © 2020-2023  润新知