zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    湘潭oj1203/邀请赛A称号 数论+java睑板
    Ejb in action(七)——message与JMS
    Post和Get差异
    1.cocos2dx它Menu(CCMenuItemFont,CCMenuItemImage,CCMenuItemLabel,CCMenuItemSprite,CCMenuItemToggle)
    ftk学习记录(IME文章)
    内部类创建一个内部版本
    使用gson和httpclient呼叫微信公众平台API
    hdu
    Beginning Python From Novice to Professional (5) - 条件与循环
    24点经典算法
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9768923.html
Copyright © 2011-2022 走看看