zoukankan      html  css  js  c++  java
  • 【SDOI2018】战略游戏

    题面

    https://www.luogu.org/problem/P4606

    题解

    又一次被$aysn$吊打。

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define N 200000
    #define ri register int
    using namespace std;
    
    int n,m,q,s,T,cnt,clo;
    int dfn[N],low[N],stk[N],top,bel[N];
    int f[N][25];
    int dfin[N],dfou[N],d[N];
    vector<int> to[N],syx[N];
    int a[N*2],ss[N*2],yy[N],stop,siz[N];
    bool vis[N];
    
    bool cmp1(int x,int y){
      return dfin[x]<dfin[y];
    }
    
    bool cmp2(int x,int y){
      int k1,k2;
      if (x>0) k1=dfin[x]; else k1=dfou[-x];
      if (y>0) k2=dfin[y]; else k2=dfou[-y];
      return k1<k2;
    }
    
    void tarjan(int x,int ff){
      dfn[x]=low[x]=++clo;
      stk[++top]=x;
      for (ri i=to[x].size()-1;i>=0;i--) if (to[x][i]!=ff) {
        if (!dfn[to[x][i]]) {
          tarjan(to[x][i],x);
          low[x]=min(low[x],low[to[x][i]]);
          if (low[to[x][i]]>=dfn[x]) {
            cnt++;
            int cc;
            do {
              cc=stk[top];
              syx[cnt].push_back(cc);
              syx[cc].push_back(cnt); 
              top--;
            }
            while (cc!=to[x][i]);
            syx[cnt].push_back(x); syx[x].push_back(cnt); 
          }
        }
        else low[x]=min(dfn[to[x][i]],low[x]);
      }
    }
    
    void dfs(int x,int ff) {
      f[x][0]=ff; d[x]=d[ff]+1; yy[x]=yy[ff]+(x<=n);
      for (ri i=1;i<=20;i++) f[x][i]=f[f[x][i-1]][i-1];
      dfin[x]=++cnt;
      for (ri i=syx[x].size()-1;i>=0;i--) if (syx[x][i]!=ff) dfs(syx[x][i],x);
      dfou[x]=++cnt;
    }
    
    int lca(int x,int y){
      if (d[x]<d[y]) swap(x,y);
      for (ri i=20;i>=0;i--) if (d[f[x][i]]>=d[y]) x=f[x][i];
      if (x==y) return x;
      for (ri i=20;i>=0;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
      return f[x][0];
    }
    
    int main(){
      scanf("%d",&T);
      for (ri ti=1;ti<=T;ti++) {
        scanf("%d %d",&n,&m);
        int u,v;
        for (ri i=1;i<=m;i++) {
          scanf("%d %d",&u,&v);
          to[u].push_back(v); to[v].push_back(u);
        }
        clo=0; top=0; cnt=n;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(bel,0,sizeof(bel));
        tarjan(1,1);
        cnt=0;
        d[1]=0; yy[1]=0;
        dfs(1,1);
        scanf("%d",&q);
        for (ri ii=1;ii<=q;ii++) {
          scanf("%d",&s);
          int t=s;
          for (ri i=1;i<=s;i++) {
            scanf("%d",&a[i]);
            vis[a[i]]=1;
          }
          sort(a+1,a+s+1,cmp1);
          int ns=s;
          for (ri i=1;i<ns;i++) {
            int t=lca(a[i],a[i+1]);
            if (!vis[t]) a[++s]=t,vis[t]=1;
          }
          ns=s;
          for (ri i=1;i<=ns;i++) a[++s]=-a[i];
          sort(a+1,a+s+1,cmp2);
          stop=0;
          for (ri i=1;i<=s;i++) if (a[i]>0) {
            ss[++stop]=a[i];
            if (a[i]<=n) siz[a[i]]++;
          }
          else {
            stop--;
            if (stop) siz[ss[stop]]+=(siz[-a[i]]+yy[-a[i]]-(-a[i]<=n)-yy[ss[stop]]);
          }
          printf("%d
    ",siz[a[1]]-t);
          for (ri i=1;i<=s;i++) if (a[i]>0) siz[a[i]]=0,vis[a[i]]=0;
        }
        for (ri i=1;i<=cnt;i++) to[i].clear();
        for (ri i=1;i<=cnt;i++) syx[i].clear();
      }
    }
  • 相关阅读:
    QT中的定时器使用
    range()函数常和len()函数一起用于字符串索引。在这里我们要显示每一个元素及其索引值。
    range()的print 《P核》P30
    2.13 带逗号的print语句输出的元素之间自动带个空格
    Python3.x和Python2.x的区别
    print语句默认每行添加一个换行符 来自2.13
    2.12 while循环 print与计数器先后顺序对结果的影响
    函数本地绑定与全局绑定的区别
    字典映射{ :}
    《Python核心编程》P21输入数值字符串→转整型
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11278543.html
Copyright © 2011-2022 走看看