zoukankan      html  css  js  c++  java
  • [BZOJ5329][SDOI2018]战略游戏(圆方树+虚树)

    题意:一张无向图,每次给出一个点集,问有多少个点满足删去它后,存在点集中的两个点不连通。

    算法:显然的圆方树+虚树。

    建出圆方树后,答案就是所有关键点之间的路径上的圆点个数,这个直接用虚树,维护树上前缀和与右链即可。

    虚树一万年不会建。。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define rep(i,l,r) for (int i=(l),_=(r); i<=_; i++)
     5 #define mem(a) memset(a,0,sizeof(a))
     6 using namespace std;
     7 
     8 const int N=400010;
     9 int n,tot,k,u,v,m,T,Q,top,clk,L[N],R[N],dfn[N],low[N],tim,stk[N];
    10 int fa[N],Top[N],dep[N],dis[N],s[N],sz[N],son[N],q[N];
    11 struct E{
    12     int cnt,h[N],nxt[N],to[N];
    13     void init(){ mem(h); cnt=0; }
    14     void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
    15 }G,G1;
    16 
    17 void Tarjan(int x,int fa){
    18     dfn[x]=low[x]=++tim; stk[++top]=x;
    19     for (int i=G.h[x],k; i; i=G.nxt[i])
    20         if ((k=G.to[i])!=fa){
    21             if (!dfn[k]){
    22                 Tarjan(k,x); low[x]=min(low[x],low[k]);
    23                 if (low[k]>=dfn[x]){
    24                     tot++; int t; G1.add(x,tot);
    25                     do { t=stk[top--]; G1.add(tot,t); } while (t!=k);
    26                 }
    27             }else low[x]=min(low[x],dfn[k]);
    28         }
    29 }
    30 
    31 void dfs1(int x){
    32     dep[x]=dep[fa[x]]+1; dis[x]=dis[fa[x]]+(x<=n); sz[x]=1;
    33     for (int i=G1.h[x]; i; i=G1.nxt[i]){
    34         int k=G1.to[i]; fa[k]=x; dfs1(k); sz[x]+=sz[k];
    35         if (sz[k]>sz[son[x]]) son[x]=k;
    36     }
    37 }
    38 
    39 void dfs2(int x,int tp){
    40     Top[x]=tp; L[x]=++clk;
    41     if (son[x]) dfs2(son[x],tp);
    42     for (int i=G1.h[x],k; i; i=G1.nxt[i])
    43         if ((k=G1.to[i])!=son[x]) dfs2(k,k);
    44     R[x]=clk;
    45 }
    46 
    47 int LCA(int u,int v){
    48     for (; Top[u]!=Top[v]; u=fa[Top[u]])
    49         if (dep[Top[u]]<dep[Top[v]]) swap(u,v);
    50     return dep[u]<dep[v] ? u : v;
    51 }
    52 
    53 bool cmp(int a,int b){ return L[a]<L[b]; }
    54 
    55 int main(){
    56     freopen("bzoj5329.in","r",stdin);
    57     freopen("bzoj5329.out","w",stdout);
    58     for (scanf("%d",&T); T--; ){
    59         scanf("%d%d",&n,&m); tot=n;
    60         tim=clk=0; mem(dfn); mem(son); G.init(); G1.init();
    61         rep(i,1,m) scanf("%d%d",&u,&v),G.add(u,v),G.add(v,u);
    62         rep(i,1,n) if (!dfn[i]) Tarjan(i,0);
    63         dfs1(1); dfs2(1,1);
    64         for (scanf("%d",&Q); Q--; ){
    65             scanf("%d",&k); int len=k;
    66             rep(i,1,k) scanf("%d",&s[i]);
    67             sort(s+1,s+k+1,cmp);
    68             rep(i,1,k-1) s[++len]=LCA(s[i],s[i+1]);
    69             sort(s+1,s+len+1,cmp); len=unique(s+1,s+len+1)-s-1;
    70             int tp=0,ans=(s[1]<=n);
    71             rep(i,1,len){
    72                 while (tp && R[q[tp]]<L[s[i]]) tp--;
    73                 if (tp) ans+=dis[s[i]]-dis[q[tp]];
    74                 q[++tp]=s[i];
    75             }
    76             printf("%d
    ",ans-k);
    77         }
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    VMware Workstation 8.0.0 安装 Red Hat5.3
    Struts2 结合HttpClient 实现远程服务器文件下载
    按位与、或、异或等运算方法
    Java中实例方法、类方法和构造方法
    JAVA中类、实例与Class对象
    Shell学习笔记——循环
    placement new带来的rapidxml.hpp编译错误
    从GitHub下载CocosBuilder2.1的源码
    Visual Studio中,同一个solution内多个project之间的引用
    cocos2dx中让根节点的opacity影响孩子节点
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9147015.html
Copyright © 2011-2022 走看看