• [Luogu P5068][Ynoi2015]我回来了


    题目链接:

    Luogu P5068 [Ynoi2015]我回来了

    首先这题并不难,只是duliu卡常数罢了,是Ynoi里面比较友好的一道题。

    先预处理(f[i][j])表示(Dist(i,k)le j)的点(k)集合,那么对每一个点BFS一遍

    然后求答案的话取个并集就好了。

    以上步骤都可以用bitset加速

    时间复杂度 (O(nm+frac{n^3}{32}+frac{nsum a}{32}))

    还有一点,分析复杂度你会发现BFS竟然是这个题复杂度的瓶颈。。

    如果你使用前向星存图就会全部TLE,可以用std::vector或者开(n)个栈来存图(这题要判重边),这样由于内存连续就可以卡Cache从而AC

    全手写了一遍,卡了Luogu Rank2,卡常真好玩

    代码:

    //Absoulute LanrTabe
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #define rint register int
    typedef unsigned int ui;
    
    #define Getchar (p1==p2&&(p2=(p1=In)+fread(In,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    char In[1<<21],*p1=In,*p2=In,Ch;
    inline int Getint(rint x=0)
    {
        while(!isdigit(Ch=Getchar));
        for(;isdigit(Ch);Ch=Getchar)x=x*10+(Ch^48);
        return x;
    }
    
    inline int Min(const int a,const int b){return a<b?a:b;}
    
    const ui Mui=0xffffffff;
    int Cnt[1<<16];
    struct Bitset
    {
        ui a[33];
        inline void Set(){memset(a,0xff,sizeof a);}
        inline void Reset(){memset(a,0,sizeof a);}
        inline void Set(const int p){a[p>>5]|=1u<<(p&0x1f);}
        int Count(rint s=0){for(rint i=0;i<33;++i)s+=Cnt[a[i]&0xffff]+Cnt[a[i]>>16&0xffff];return s;}
        inline void operator|=(const Bitset &o){for(rint i=0;i<33;++i)a[i]|=o.a[i];}
    }f[1005][1005],S;
    
    int n,m,q,G[1005][1005],Gs[1005];
    int Dis[1005],Q[1005],Qh,Qt,Md[1005];
    bool Gv[1005][1005];
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        for(rint i=1;i<=0xffff;++i)Cnt[i]=Cnt[i>>1]+(i&1);
        n=Getint(),m=Getint(),q=Getint();
        for(rint x,y;m--;)
        {
            x=Getint(),y=Getint();
            if(!Gv[x][y]&&!Gv[y][x])G[x][++Gs[x]]=y,G[y][++Gs[y]]=x,Gv[x][y]=Gv[y][x]=true;
        }
        for(rint s=1;s<=n;++s)
        {
            memset(Dis,-1,sizeof Dis),Dis[Q[Qh=Qt=1]=s]=0;
            for(rint x,d;Qh<=Qt;)
            {
                d=Dis[x=Q[Qh++]],Md[s]=d,f[s][d].Set(x);
                for(rint i=Gs[x],y;i>=1;--i)if(Dis[y=G[x][i]]==-1)Dis[Q[++Qt]=y]=d+1;
            }
            for(rint i=1;i<=Md[s];++i)f[s][i]|=f[s][i-1];
        }
        for(rint a,x,y;q--;printf("%d
    ",S.Count()))
            for(S.Reset(),a=Getint();a--;S|=f[x][Min(y,Md[x])])
                x=Getint(),y=Getint();
        return 0;
    }
    
  • 相关阅读:
    [转]十个让你变成糟糕的程序员的行为
    [转]CKEDITOR 使用说明
    [转]惹恼程序员的十件事
    基本权限管理框架配套代码生成器!
    Easy UI 点击TAB 标签 刷新内容
    jQuery.easyui 与 jQuery.Valiedate 验证控件组合使用实例!
    [转]十条不错的编程观点
    dos 改 ip
    今天碰到了几个老同学,哎,,感觉
    猛玩War3中
  • 原文地址:https://www.cnblogs.com/LanrTabe/p/11598388.html
Copyright © 2020-2023  润新知