zoukankan      html  css  js  c++  java
  • BZOJ 5329: [Sdoi2018]战略游戏 (圆方树,树链的并)

    一定注意,这里不要写错:  

    $low[y]>=dfn[x]$,开始的时候把 $dfn[x]$ 写成 $low[x]$ 调了一下午......    

    然后根据圆方树优美的性质,我们发现题中要求的就是圆方树上一些点构成的树链的并中圆点个数.   

    这个问题可以用虚树或树链的并解决.  

    code:   

    #include <cstdio> 
    #include <cstring> 
    #include <algorithm>   
    #include <vector>     
    #define N 200006   
    #define setIO(s) freopen(s".in","r",stdin)  , freopen(s".out","w",stdout) 
    using namespace std;       
    vector<int>G[N];  
    int edges,tim,fr,tot,n,m,Q;                
    int hd[N<<1],to[N<<1],nex[N<<1],dfn[N],low[N],S[N];   
    int dn[N],dep[N],size[N],son[N],top[N],fa[N],depth[N];    
    int arr[N];      
    bool cmp(int a,int b) 
    {
        return dn[a]<dn[b];  
    }
    void add(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;  
    } 
    void tarjan(int x) 
    {
        dfn[x]=low[x]=++tim;      
        S[++fr]=x;     
        for(int i=hd[x];i;i=nex[i]) 
        {
            int y=to[i];     
            if(!dfn[y]) 
            {
                tarjan(y);   
                low[x]=min(low[x],low[y]);    
                if(low[y]>=dfn[x]) 
                {
                    ++tot;         
                    G[x].push_back(tot); 
                    G[tot].push_back(x);  
                    for(int p=0;p!=y;--fr) 
                    {
                        p=S[fr];        
                        G[tot].push_back(p); 
                        G[p].push_back(tot);      
                    }               
                }
            }   
            else {
                low[x]=min(low[x],dfn[y]);               
            }
        }    
    }     
    void dfs1(int x,int ff) 
    {     
        dn[x]=++tim,depth[x]=depth[ff]+1;    
        fa[x]=ff,size[x]=1,dep[x]=dep[ff]+(x<=n);       
        for(int i=0;i<G[x].size();++i) 
        {
            int y=G[x][i];   
            if(y==ff) continue;           
            dfs1(y,x);   
            if(size[y]>size[son[x]])  
                son[x]=y;   
            size[x]+=size[y];  
        }
    }
    void dfs2(int x,int tp) 
    {
        top[x]=tp;        
        if(son[x])   
            dfs2(son[x],tp);   
        for(int i=0;i<G[x].size();++i) 
        {
            if(G[x][i]!=fa[x]&&G[x][i]!=son[x])  
                dfs2(G[x][i],G[x][i]); 
        }
    }   
    int get_lca(int x,int y) 
    {
        while(top[x]!=top[y]) 
        {  
            depth[top[x]]>depth[top[y]]?x=fa[top[x]]:y=fa[top[y]];  
        } 
        return depth[x]<depth[y]?x:y;   
    }         
    void calc() 
    {
        int num,lca; 
        scanf("%d",&num);    
        for(int i=1;i<=num;++i)
            scanf("%d",&arr[i]);          
        sort(arr+1,arr+1+num,cmp);        
        for(int i=1;i<=num;++i) 
        { 
            if(i==1) lca=arr[1];  
            else lca=get_lca(lca,arr[i]);
        } 
        int ans=0;    
        for(int i=1;i<=num;++i) 
            ans+=dep[arr[i]]-dep[fa[lca]];   
        for(int i=2;i<=num;++i) 
        {
            int p=get_lca(arr[i],arr[i-1]);    
            ans-=(dep[p]-dep[fa[lca]]);       
        }                
        printf("%d
    ",ans-num);    
    }
    void solve() 
    {
        scanf("%d%d",&n,&m);   
        for(int i=1;i<=m;++i) 
        {
            int x,y;   
            scanf("%d%d",&x,&y);              
            add(x,y),add(y,x); 
        }        
        tot=n;
        tarjan(1);     
        tim=0;    
        dfs1(1,0); 
        dfs2(1,1);           
        scanf("%d",&Q);       
        for(int i=1;i<=Q;++i) calc();    
        for(int i=0;i<=2*n;++i)  
        {
            G[i].clear();    
            low[i]=dfn[i]=son[i]=dep[i]=depth[i]=fa[i]=0;    
        }
        for(int i=0;i<=edges;++i) 
            nex[i]=to[i]=0;     
        for(int i=0;i<=n;++i) 
            hd[i]=0;        
        edges=tim=fr=tot=0; 
    
    }
    int main() 
    { 
        // setIO("input"); 
        int T;  
        scanf("%d",&T);   
        while(T--) solve();  
        return 0; 
    }
    

      

  • 相关阅读:
    my15_ mysql binlog格式从mixed修改为row格式
    my14_mysql指定时间恢复之模拟从库
    my13_mysql xtrabackup备份的时间点
    必知必会的图论算法
    leetcde37. Sudoku Solver
    leetcode36. Valid Sudoku
    leetcode52. N-Queens II
    leetcode51. N-Queens
    First Missing Positive
    Maximum Gap
  • 原文地址:https://www.cnblogs.com/guangheli/p/12589063.html
Copyright © 2011-2022 走看看