zoukankan      html  css  js  c++  java
  • Luogu P4606 [SDOI2018] 战略游戏 圆方树 虚树

    https://www.luogu.org/problemnew/show/P4606

    把原来的图的点双联通分量缩点(每个双联通分量建一个点,每个割点再建一个点)(用符合逻辑的方式)建一棵树(我最开始建的想法就有问题,答案竟然还差不多,查了好久才发现……然后重新想了个正确的建法发现比之前那个错误的建法好写多了,气),然后把这棵树整成虚树再做个树上dp就(安排得)明明白白的了。dp的时候注意一下树的根的值也要统计。

    我的程序大概常数太大了洛谷开O2才能过,BZOJ会tle,也不想改了,就这样吧……

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 using namespace std;
      7 const int maxn=500010;
      8 int n,m;
      9 struct nod{
     10     int y,next;
     11 };nod e1[maxn*8];nod e[maxn*8];nod e2[maxn*8];
     12 int head1[maxn]={},head[maxn]={},tot1=0,tot=0;
     13 int head2[maxn]={},tot2=0;
     14 int dfn[maxn]={},low[maxn]={},bel[maxn]={},bel1[maxn]={},poi[maxn]={},sta[maxn]={},tai,cnt,tn;
     15 int val[maxn]={};
     16 int pa[maxn]={};
     17 void init1(int x,int y){ e1[++tot1].y=y;e1[tot1].next=head1[x];head1[x]=tot1; }
     18 void init(int x,int y){ e[++tot].y=y;e[tot].next=head[x];head[x]=tot; }
     19 void init2(int x,int y){ e2[++tot2].y=y;e2[tot2].next=head2[x];head2[x]=tot2; }
     20 int getpa(int x){return x==pa[x]?x:getpa(pa[x]);}
     21 void merpa(int x,int y){
     22     x=getpa(x);y=getpa(y);
     23     pa[x]=pa[y];
     24 }
     25 void Tarjan(int x,int p){
     26     dfn[x]=low[x]=++cnt;sta[++tai]=x; int z=0;
     27     for(int i=head1[x];i;i=e1[i].next){
     28         if(e1[i].y==p)continue;
     29         if(!dfn[e1[i].y]){
     30             Tarjan(e1[i].y,x);
     31             low[x]=min(low[e1[i].y],low[x]);
     32             if(low[e1[i].y]>=dfn[x]){
     33                 int w; ++tn;++z;
     34                 if(low[e1[i].y]==dfn[x]&&!p)bel[x]=tn;
     35                 do{
     36                     w=sta[tai--];
     37                     bel[w]=tn;
     38                 }while(w!=e1[i].y);
     39             }
     40         }
     41         else low[x]=min(low[x],dfn[e1[i].y]);
     42     }
     43     if(z>=1&&p){
     44         poi[x]=1;
     45         bel1[x]=++tn;
     46     }
     47     if(!p){
     48         if(z>1){poi[x]=1;bel1[x]=++tn;}
     49         if(!bel[x])bel[x]=++tn;
     50     }
     51 }
     52 void dfs1(int x){
     53     for(int i=head1[x];i;i=e1[i].next){
     54         int y=e1[i].y;
     55         if(poi[y]){
     56             if(getpa(bel1[y])!=getpa(bel[x])){
     57                 init(bel1[y],bel[x]);init(bel[x],bel1[y]);
     58                 merpa(bel1[y],bel[x]);
     59             }
     60         }
     61     }
     62 }
     63 void dfs11(int x){
     64     for(int i=head1[x];i;i=e1[i].next){
     65         int y=e1[i].y;
     66         if(poi[y]){
     67             if(getpa(bel1[y])!=getpa(bel1[x])){
     68                 init(bel1[y],bel1[x]);init(bel1[x],bel1[y]);
     69                 merpa(bel1[y],bel1[x]);
     70             }
     71         }
     72     }
     73 }
     74 int dep[maxn]={},fa[maxn][30]={},id[maxn]={},shu;
     75 int a[maxn]={},val1[maxn];
     76 void dfs(int x,int p){
     77     dep[x]=dep[p]+1;fa[x][0]=p;val[x]=val[p]+val1[x];id[x]=++shu;
     78     //cout<<x<<shu<<endl;
     79     for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
     80     for(int i=head[x];i;i=e[i].next){
     81         if(e[i].y==p)continue;
     82         dfs(e[i].y,x);
     83     }
     84 }
     85 bool mcmp(int x,int y){
     86     return id[x]<id[y];
     87 }
     88 int getlca(int x,int y){
     89     if(dep[x]<dep[y])swap(x,y);
     90     if(dep[x]!=dep[y])for(int i=20;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
     91     if(x==y)return x;
     92     for(int i=20;i>=0;i--)if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}
     93     return fa[x][0];
     94 }
     95 int dfs2(int x){
     96     int ans=0;//cout<<x<<endl;
     97     for(int i=head2[x];i;i=e2[i].next){//cout<<x<<e2[i].y<<endl;
     98         ans+=dfs2(e2[i].y);
     99         ans+=val[e2[i].y]-val[x];
    100     }
    101     return ans;
    102 }
    103 void dfs3(int x){
    104     for(int i=head2[x];i;i=e2[i].next){
    105         dfs3(e2[i].y);
    106     }head2[x]=0;
    107 }
    108 void solve(){
    109     int nm;scanf("%d",&nm);
    110     int tly=1,w=0;
    111     for(int i=1;i<=nm;i++){ scanf("%d",&a[i]); if(poi[a[i]]){a[i]=bel1[a[i]]; }else a[i]=bel[a[i]];}
    112     sort(a+1,a+1+nm,mcmp);
    113     for(int i=2;i<=nm;i++)if(a[tly]!=a[i])a[++tly]=a[i];
    114     tot2=0;tai=1;sta[1]=a[1];w-=val1[a[1]];
    115     for(int i=2;i<=tly;i++){
    116         int lc=getlca(sta[tai],a[i]);w-=val1[a[i]];//cout<<a[i]<<sta[tai]<<lc<<endl;
    117         while(tai&&dep[lc]<dep[sta[tai]]){
    118             if(tai==1||(tai>1&&dep[sta[tai-1]]<dep[lc])){
    119                 init2(lc,sta[tai]);tai--;break;
    120             }
    121             if(tai-1>0)init2(sta[tai-1],sta[tai]);
    122             tai--;
    123         }
    124         if(sta[tai]!=lc||!tai)sta[++tai]=lc;
    125         if(sta[tai]!=a[i]||!tai)sta[++tai]=a[i];
    126     }
    127     while(--tai){init2(sta[tai],sta[tai+1]);}
    128     w+=dfs2(sta[1]); dfs3(sta[1]);
    129     //cout<<tly<<' '<<a[1]<<' '<<a[2]<<endl;
    130     //cout<<sta[1]<<' '<<getlca(a[1],a[2])<<endl;
    131     w+=val1[sta[1]];
    132     cout<<w<<endl;
    133 }
    134 int main(){
    135     //freopen("game.in","r",stdin);
    136     //freopen("game.out","w",stdout);
    137     int T;scanf("%d",&T);
    138     while(T-->0){
    139         scanf("%d%d",&n,&m);
    140         memset(dfn,0,sizeof(dfn));
    141         memset(poi,0,sizeof(poi));
    142         memset(low,0,sizeof(low));
    143         memset(bel,0,sizeof(bel));
    144         memset(bel1,0,sizeof(bel1));
    145         memset(head1,0,sizeof(head1));
    146         memset(head2,0,sizeof(head2));
    147         memset(head,0,sizeof(head));
    148         memset(fa,0,sizeof(fa));
    149         memset(val,0,sizeof(val));
    150         memset(val1,0,sizeof(val1));
    151         tot1=0,tot2=0,tot=0;cnt=0;tn=0;tai=0;shu=0;
    152         int x,y;
    153         for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);if(x==y)continue;init1(x,y);init1(y,x);}
    154         Tarjan(1,0);for(int i=1;i<=tn;i++)pa[i]=i;
    155         for(int i=1;i<=n;i++){
    156             if(poi[i]){
    157                 val1[bel1[i]]=1;
    158                 if(getpa(bel[i])!=getpa(bel1[i])){init(bel[i],bel1[i]);init(bel1[i],bel[i]);merpa(bel1[i],bel[i]);}
    159             }else dfs1(i);
    160             /*cout<<bel[i]<<bel1[i]<<poi[i]<<endl;*/
    161         }
    162         for(int i=1;i<=n;i++){
    163             if(poi[i])dfs11(i);
    164         }
    165         dfs(1,0);
    166         int q;scanf("%d",&q);
    167         for(int i=1;i<=q;i++)solve();
    168     }
    169     return 0;
    170 }
    View Code
  • 相关阅读:
    获取计算机名称
    imagelist用法
    cxgrid的ImageComboBox属性学习
    MlskincolorButton使用方法
    delphi实现窗体组建随窗体大小改变而改变
    判断路径下文件是否存在
    Delphi 按Esc快捷键退出程序的简单方法
    pagecontrol
    LinkedList源码解析
    ArrayList源码分析
  • 原文地址:https://www.cnblogs.com/137shoebills/p/9070272.html
Copyright © 2011-2022 走看看