• bzoj 5329 战略游戏


    题目大意:

    一个无向图 Q个询问 每次给一些点的集合

    求有多少个点满足去掉这个点后使这些点的集合中有一个点对不连通

    思路:

    点双缩点 相当于每次求这些点中的所有路径上的圆点个数

    可以将这些点按dfs序排序 每次求a i 和 a i+1两个点路径上的圆点个数

    最后答案/2 后减去这些点的个数(因为不能取这些点) 再判断 a i 和a n的lca是否是圆点

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 400100
    12 #define V1 (g1.to[i])
    13 #define V2 (g2.to[i])
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 int n,m;
    23 int dfn[MAXN],st[MAXN],low[MAXN],top,stp;
    24 int f[MAXN][18],dep[MAXN],dis[MAXN];
    25 struct graph
    26 {
    27     int fst[MAXN],nxt[MAXN<<2],to[MAXN<<2],cnt;
    28     void mem(){memset(fst,0,sizeof(fst));cnt=0;}
    29     void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    30 }g1,g2;
    31 void tarjan(int x)
    32 {
    33     dfn[x]=low[x]=++stp,st[++top]=x;int now=0;
    34     for(int i=g1.fst[x];i;i=g1.nxt[i])
    35         if(!dfn[V1])
    36         {
    37             tarjan(V1);low[x]=min(low[x],low[V1]);
    38             if(low[V1]<dfn[x]) continue;m++;
    39             do{now=st[top--];g2.add(m,now);}
    40             while(now!=V1);g2.add(x,m);
    41         }
    42         else low[x]=min(low[x],dfn[V1]);
    43 }
    44 void dfs(int x)
    45 {
    46     dfn[x]=++stp;
    47     for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
    48     for(int i=g2.fst[x];i;i=g2.nxt[i])
    49         {f[V2][0]=x,dep[V2]=dep[x]+1,dis[V2]=dis[x]+(V2<=n);dfs(V2);}
    50 }
    51 int lca(int a,int b)
    52 {
    53     if(dep[a]<dep[b]) swap(a,b);
    54     int t=dep[a]-dep[b];
    55     for(int i=17;i>=0;i--) if((1<<i)&t) a=f[a][i];
    56     if(a==b) return a;
    57     for(int i=17;i>=0;i--) if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
    58     return f[a][0];
    59 }
    60 bool cmp(const int &a,const int &b) {return dfn[a]<dfn[b];}
    61 inline int calc(int a,int b) {return dis[a]+dis[b]-(dis[lca(a,b)]<<1);}
    62 int main()
    63 {
    64     int T=read(),a,b,k,q,res;
    65     while(T--)
    66     {
    67         g1.mem();g2.mem();memset(dfn,0,sizeof(dfn));
    68         memset(f,0,sizeof(f));
    69         n=read(),m=read(),stp=top=0;
    70         while(m--) {a=read(),b=read();g1.add(a,b);g1.add(b,a);}
    71         m=n;tarjan(1);dis[1]=dep[1]=1,stp=0;dfs(1);
    72         q=read();
    73         while(q--)
    74         {
    75             k=read(),top=0,res=0;
    76             while(k--) st[++top]=read();
    77             sort(st+1,st+top+1,cmp);
    78             for(int i=1;i<=top;i++)
    79                 res+=calc(st[i],st[i%top+1]);
    80             if(lca(st[1],st[top])<=n) printf("%d
    ",(res+2-top*2)>>1);
    81             else printf("%d
    ",(res-top*2)>>1);
    82         }
    83     }
    84 }
    View Code
  • 相关阅读:
    1、Jenkins的安装与简单配置
    2、jenkins+svn自动发布和回滚
    关于kafka生产者相关监控指标的理解(未解决)
    Zabbix中获取各用户告警媒介分钟级统计
    2-4、配置Filebeat使用logstash
    JS基础 浏览器弹出的三种提示框(提示信息框、确认框、输入文本框)
    C# winform 托盘控件的使用
    c# 将两个表的有效数据合到一个表中
    C# 认识 接口
    let 和 var 定义变量的区别
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9768923.html
Copyright © 2020-2023  润新知