题解 CF711D 【Directed Road】

Hexarhy

2021-03-19 21:39:50

Solution

### Preface 虽说是基环树,但感觉零基础人思考起来还是蛮容易的。 可以当作图论简单思维题~~基环树味淡~~。 ### Solution **慢慢读题很重要。** 稍微熟悉的话不难发现给定的是一个基环树。 对于一个 $n$ 条边的连通子图中,节点数为 $t$ 的环,能成环的方案只能是所有边指向同一方向,也就是只有 $2$ 种方案会形成环,即合法方案数为 $2^t-2$。 剩下的边方向就随意,方案数为 $2^{n-t}$。 那么一个连通子图的总方案就为 $2^{n-t}(2^t-2)$ 每个连通子图都是互不影响的,那么整张图的方案数显然为: $$\prod 2^{n_i-t_i}(2^{t_i}-2)$$ 把其中一项提出来就可以得到大部分题解的式子: $$2^{n-\sum t_i}\prod(2^{t_i}-2)$$ 快速幂计算即可。 ### Code ```cpp void dfs(cint u,cint depth)//常见的找环方法 { dep[u]=depth; visit[u]=1; for(const auto& v:edge[u]) { if(!visit[v]) dfs(v,depth+1); else if(visit[v]==1) ring.emplace_back(dep[u]-dep[v]+1);//记录环的大小 } visit[u]=2; } int main() { cin>>n; for(int i=1;i<=n;i++) { int x;cin>>x; edge[i].emplace_back(x); } for(int i=1;i<=n;i++) if(!dep[i]) dfs(i,1); cint sum=accumulate(ring.begin(),ring.end(),0);//计算 sigma ti for(const auto& t:ring) res=res*(qpow(2,t)-2+MOD)%MOD; ll ans=res*qpow(2,n-sum)%MOD; cout<<ans<<endl; return 0; } ```