• XJOI——NOIP2015提高组模拟题19-day1——观光旅行


    http://www.hzxjhs.com:83/contest/493/problem/3

    【题目大意】

    给定一个有n(n<=500000)个点,m(1<=500000)条边的无向图。给Q(1<=500000)个询问ui和vi,问ui和vi之间是否存在一条不经过重复点的路径,使得经过的点数为偶数。

    【题目解析】

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cctype>
    
    using namespace std;
    
    #define re(i,a,b) for(i=(a);i<=(b);i++)
    #define red(i,a,b) for(i=(a);i>=(b);i--)
    
    #define SF scanf
    #define PF printf
    #define mmst(a,v) memset(a,v,sizeof(a))
    
    int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxn=500000;
    
    int n,m,Q;
    int now,info[maxn+100];
    struct Tedge{int v,next;}edge[2*maxn+100];
    int treeedge[2*maxn+100];
    
    void addedge(int u,int v){now++;edge[now].v=v;edge[now].next=info[u];info[u]=now;}
    
    int dep[maxn+100],jump[maxn+100][31];
    int odd[maxn+100],f[maxn+100];
    
    void dfs(int u)
      {
          int i,j,v;
          for(i=info[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)
            if(!dep[v])
              {
                  dep[v]=dep[u]+1;
                  jump[v][0]=u;
                  re(j,1,25)jump[v][j]=jump[jump[v][j-1]][j-1];
                  treeedge[i]=treeedge[i^1]=1;
                  dfs(v);
                  odd[u]+=odd[v];
              }
            else
              if(!treeedge[i] && dep[u]>dep[v] && (dep[u]-dep[v])%2==0)
                {
                    odd[u]++;
                    odd[v]--;
                }
      }
    
    void dfs2(int u)
      {
          int i,v;
          f[u]=f[jump[u][0]]+odd[u];
          for(i=info[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(treeedge[i] && dep[v]>dep[u])dfs2(v);
      }
    
    void swim(int &x,int H){int i;for(i=0;H!=0;H>>=1,i++)if(H&1)x=jump[x][i];}
    int ask_lca(int x,int y)
      {
          if(dep[x]<dep[y])swap(x,y);
          swim(x,dep[x]-dep[y]);
          if(x==y)return x;
          int j;
          red(j,25,0)if(jump[x][j]!=jump[y][j])x=jump[x][j],y=jump[y][j];
          return jump[x][0];
      }
    
    int main()
      {
          freopen("travel.in","r",stdin);
          freopen("travel.out","w",stdout);
          int i,j;
          n=gint();m=gint();Q=gint();
          now=-1;mmst(info,-1);
          re(i,1,m)
            {
                int x=gint(),y=gint();
                addedge(x,y);addedge(y,x);
            }
          dep[1]=1;
          re(j,0,25)jump[1][j]=1;
          dfs(1);
          re(i,1,n)if(odd[i])odd[i]=1;
          dfs2(1);
          while(Q--)
            {
                int x=gint(),y=gint();
                    int lca=ask_lca(x,y);
                    if((dep[x]-dep[lca]+dep[y]-dep[lca])%2==1 || f[x]-f[lca]>=1 || f[y]-f[lca]>=1)PF("TAK
    ");else PF("NIE
    ");
                }
            return 0;
        }
    View Code
  • 相关阅读:
    kali禁止自动挂载U盘(gnome)
    Kali开启远程桌面服务(gnome桌面环境)
    KVM安装Win7时USB3.0无法使用的坑
    Linux上VLAN的创建
    小程序 局部页面 自定义滚动条
    两个图层一上一下div view
    js 数组去重
    css > 的写法 html
    块级元素和行内元素
    小程序 css 文字溢出,长度过长用 。。。
  • 原文地址:https://www.cnblogs.com/maijing/p/4940015.html
Copyright © 2020-2023  润新知