zoukankan      html  css  js  c++  java
  • 【HDOJ6604】Blow up the city(支配树)

    题意:给定一个n点m边的DAG,将只有入边的点称为周驿东点

    q次询问,每次给定a,b两点,询问删去某个点x和其相连的所有边,能使a,b至少其中之一不能到达任何周驿东点的x的个数

    n,q<=1e5,m<=2e5

    思路:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 #define N  210000
     10 #define M  1100000
     11 #define fi first
     12 #define se second
     13 #define MP make_pair
     14 #define pi acos(-1)
     15 #define mem(a,b) memset(a,b,sizeof(a))
     16 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     17 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     18 #define lowbit(x) x&(-x)
     19 #define Rand (rand()*(1<<16)+rand())
     20 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     21 #define ls p<<1
     22 #define rs p<<1|1
     23 
     24 const ll MOD=998244353,inv2=(MOD+1)/2;
     25       double eps=1e-6;
     26       ll INF=1e14;
     27 
     28 vector<int> dom[N],be[N];
     29 int f[N][20],head[N],vet[N],nxt[N],dep[N],ind[N],
     30     id[N],semi[N],p[N],pa[N],dfn[N],idom[N],mn[N],tot,cnt;
     31 
     32 int read()
     33 {
     34    int v=0,f=1;
     35    char c=getchar();
     36    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     37    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     38    return v*f;
     39 }
     40 
     41 void add(int a,int b)
     42 {
     43     nxt[++tot]=head[a];
     44     vet[tot]=b;
     45     head[a]=tot;
     46 }
     47 
     48 void dfs(int u)
     49 {
     50     dfn[u]=++cnt; id[cnt]=u;
     51     int e=head[u];
     52     while(e)
     53     {
     54         int v=vet[e];
     55         if(!dfn[v])
     56         {
     57             dfs(v);
     58             pa[dfn[v]]=dfn[u];
     59         }
     60         be[dfn[v]].push_back(dfn[u]);
     61         e=nxt[e];
     62     }
     63 }
     64 
     65 int get(int x)
     66 {
     67     if(p[x]!=p[p[x]])
     68     {
     69         if(semi[mn[x]]>semi[get(p[x])]) mn[x]=get(p[x]);
     70         p[x]=p[p[x]];
     71     }
     72     return mn[x];
     73 }
     74 
     75 void LT()
     76 {
     77     per(i,cnt,2)
     78     {
     79         for(int j:be[i]) semi[i]=min(semi[i],semi[get(j)]);
     80         dom[semi[i]].push_back(i);
     81         int x=p[i]=pa[i];
     82         for(int y:dom[x]) idom[y]=(semi[get(y)]<x?get(y):x);
     83         dom[x].clear();
     84     }
     85     rep(i,2,cnt)
     86     {
     87         if(idom[i]!=semi[i]) idom[i]=idom[idom[i]];
     88         dom[id[idom[i]]].push_back(id[i]);
     89     }
     90 }
     91 
     92 void getdep(int u,int fa)
     93 {
     94     rep(i,1,19) f[u][i]=f[f[u][i-1]][i-1];
     95     int e=head[u];
     96     while(e)
     97     {
     98         int v=vet[e];
     99         if(v!=fa)
    100         {
    101             f[v][0]=u;
    102             dep[v]=dep[u]+1;
    103             getdep(v,u);
    104         }
    105         e=nxt[e];
    106     }
    107 }
    108 
    109 int lca(int x,int y)
    110 {
    111     if(dep[x]<dep[y]) swap(x,y);
    112     int d=dep[x]-dep[y];
    113     rep(i,0,19)
    114      if((d>>i)&1) x=f[x][i];
    115     per(i,19,0)
    116      if(f[x][i]!=f[y][i])
    117      {
    118          x=f[x][i];
    119          y=f[y][i];
    120      }
    121     if(x==y) return x;
    122     return f[x][0];
    123 }
    124 
    125 int main()
    126 {
    127     //freopen("1.in","r",stdin);
    128     //freopen("1.out","w",stdout);
    129     int cas=read();
    130     while(cas--)
    131     {
    132         int n=read(),m=read();
    133         tot=0;
    134         rep(i,1,n+1) head[i]=ind[i]=dfn[i]=id[i]=idom[i]=0;
    135         rep(i,1,m)
    136         {
    137             int x=read(),y=read();
    138             add(y,x);
    139             ind[x]++;
    140         }
    141         int root=n+1;
    142         rep(i,1,n)
    143          if(!ind[i]) add(root,i);
    144         rep(i,1,root)
    145         {
    146             dfn[i]=0;
    147             dom[i].clear();
    148             be[i].clear();
    149             p[i]=mn[i]=semi[i]=i;
    150         }
    151         cnt=0;
    152         dfs(root);
    153         LT();
    154         tot=0;
    155         rep(i,1,root) head[i]=0;
    156         rep(i,1,root)
    157          if(id[idom[i]]) add(id[idom[i]],id[i]);
    158         rep(i,1,root) dep[i]=0;
    159         getdep(root,0);
    160         int q=read();
    161         while(q--)
    162         {
    163             int x=read(),y=read();
    164             int t=lca(x,y);
    165             printf("%d
    ",dep[x]+dep[y]-dep[t]);
    166         }
    167     }
    168 
    169     return 0;
    170 }
  • 相关阅读:
    Catalan数(卡特兰数)
    100个乘客登机问题
    [设计模式]抽象工厂模式
    栈-队和队-栈
    java实现字符串反转
    java实现字符串按词反转
    windows上安装maven及eclipse中配置maven
    Windows 10 安装 Docker
    Win7操作系统安装IE10提示“安装前需要更新与安装程序版本”
    解决Jenkins权限配置错误,导致登录时出现没有Overall/read权限
  • 原文地址:https://www.cnblogs.com/myx12345/p/11593829.html
Copyright © 2011-2022 走看看