1 条题解

  • 0
    @ 2025-10-8 16:59:20

    E94 Tarjan边双缩点+树形DP P8867 [NOIP2022] 建造军营

    // Tarjan边双缩点+树形DP O(n)
    #include<bits/stdc++.h>
    using namespace std;
    
    int read(){
      int x=0,f=1;char c=getchar();
      while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
      while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
      return x*f;
    }
    const int N=500010,M=2000010,mod=1e9+7;
    int n,m;
    int head[N],ne[M],fr[M],to[M],idx=1;
    void add(int x,int y){
      fr[++idx]=x;to[idx]=y;ne[idx]=head[x];head[x]=idx;
    }
    vector<int> e[N];
    stack<int> s;
    int dfn[N],low[N],tim,dcc[N],sum[N],cnt,bri[M],siz[N];
    long long f[N][2],pw[M],ans;
    
    void tarjan(int x,int ine){
      dfn[x]=low[x]=++tim; s.push(x);
      for(int i=head[x];i;i=ne[i]){
        int y=to[i];
        if(!dfn[y]){
          tarjan(y,i);
          low[x]=min(low[x],low[y]);
          if(dfn[x]<low[y]) bri[i]=bri[i^1]=1;
        }
        else if(i!=(ine^1))
          low[x]=min(low[x],dfn[y]);
      }
      if(dfn[x]==low[x]){
        ++cnt;
        while(1){
          int y=s.top();s.pop();
          dcc[y]=cnt;
          ++sum[cnt];
          if(y==x)break;
        }
      }
    }
    void dfs(int x,int fa){
      siz[x]=1;
      f[x][0]=1; f[x][1]=pw[sum[x]]-1;
      for(int y:e[x]){
        if(y==fa) continue;
        dfs(y,x);
        siz[x]+=siz[y];
        f[x][1]=(f[x][1]*f[y][0]*2%mod
                +f[x][1]*f[y][1]%mod
                +f[x][0]*f[y][1]%mod)%mod;
        f[x][0]=f[x][0]*f[y][0]*2%mod;
      }
      if(x==1) siz[x]--;
      ans=(ans+f[x][1]*pw[m-siz[x]])%mod;
    }
    int main(){
      n=read();m=read();
      for(int i=1;i<=m;++i){ //建图
        int x=read(),y=read();add(x,y);add(y,x);
      }
      tarjan(1,0); //缩点
      for(int i=2;i<=idx;++i) //建树
        if(bri[i])e[dcc[fr[i]]].push_back(dcc[to[i]]);
      pw[0]=1;
      for(int i=1;i<M/2;++i) pw[i]=pw[i-1]*2%mod;
      dfs(1,0); //DP
      cout<<ans;
    }
    
    
    • 1

    信息

    ID
    1976
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    5
    已通过
    2
    上传者