zoukankan      html  css  js  c++  java
  • LYDSY模拟赛day1 Walk

    /*
    依旧考虑新增 2^20 个点。
    i 只需要向 i 去掉某一位的 1 的点连边。
    这样一来图的边数就被压缩到了 20 · 2^20 + 2n + m,然后
    BFS 求出 1 到每个点的最短路即可。
    时间复杂度 O(20 · 2^20 + n + m)
    */
    #include<cstdio>
    const int N=1300000,M=700010;
    int n,m,i,x,y,cnt,g0[N],g1[N],v[M],nxt[M],ed,h,t,q[N],d[N];
    void add(int*g,int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    void ext(int x,int w){
      if(d[x]>=0)return;
      d[q[++t]=x]=w;
      for(int i=g0[x];i;i=nxt[i])ext(v[i],w);
      if(x>=cnt)return;
      for(int i=0;i<20;i++)if(x>>i&1)ext(x^(1<<i),w);
    }
    int main(){
      freopen("walk.in","r",stdin);freopen("walk.out","w",stdout);
      scanf("%d%d",&n,&m);
      cnt=1<<20;
      for(i=1;i<=n;i++){
        scanf("%d",&x);
        add(g1,i+cnt,x);
        add(g0,x,i+cnt);
      }
      while(m--)scanf("%d%d",&x,&y),add(g1,x+cnt,y+cnt);
      for(h=i=1,t=0;i<=n+cnt;i++)d[i]=-1;
      ext(cnt+1,0);
      while(h<=t)for(i=g1[x=q[h++]];i;i=nxt[i])ext(v[i],d[x]+1);
      for(i=1;i<=n;i++)printf("%d
    ",d[i+cnt]);
      fclose(stdin);fclose(stdout);
      return 0;
    }
  • 相关阅读:
    TestNG详解-深度好文
    自动化测试用例getText()获取某一个元素的值返回null或空
    Python装饰器
    工资管理系统
    并发,并行
    TCP/IP协议
    tcp长连接和短连接
    tcp注意点
    文件下载器
    tcp服务器
  • 原文地址:https://www.cnblogs.com/hyfer/p/5928226.html
Copyright © 2011-2022 走看看