Codeforces Round #369 (Div. 2) D. Directed Roads

题目链接

题意:给你一个n个点,n条有向边的图,你可以使任意条边反向,但是每条边只能反向一次,请求出使图不存在环的所有方案数量

仔细思考我们发现,对于一个点数为x的环,除去全部不反向和全部反向两种情况,其他的所有方案总数为(2^x)-2种

对于不在环上的边,无论反向还是不反向对环的存在都是没有影响的,因此如果有y条边不在环上,就有2^y种情况

最后将所有的情况乘起来就可以了,环的存在需要dfs预处理一下

——————因为这里每个点的出度只有1,所有要成环肯定是沿着给定nxt找下去找得到。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mod 1000000007
const int maxn=200005;
int nxt[maxn],vis[maxn],loop[maxn];
int n,tot;
void findloop(int x){
   loop[tot]=1;
   vis[x]=3;
   while(vis[nxt[x]]!=3){
    x=nxt[x];
    vis[x]=3;
    loop[tot]++;
   }
}
void dfs(int x){
    vis[x]=2;
    if(!vis[nxt[x]])dfs(nxt[x]);
    if(vis[nxt[x]]==2){
        tot++;
        findloop(nxt[x]);
    }
    //if(vis[nxt[x]]==1||vis[nxt[x]]==3)
        vis[x]=1;
}
LL quickpowmod(LL x,LL y,LL mo)
{
      LL ret = 1;
      while(y){
         if(y&1)
             ret = ret*x%mo;
         x = x*x%mo;
         y >>= 1;
     }
   return ret;
 }

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&nxt[i]);
    tot=0;
    for(int i=1;i<=n;i++){
        if(!vis[i])dfs(i);
    }
    LL ans=1;
    for(int i=1;i<=tot;i++){
        ans=ans*((quickpowmod(2,loop[i],mod)-2+mod)%mod)%mod;
        n-=loop[i];
    }
    ans=ans*quickpowmod(2,n,mod)%mod;
    cout<<ans<<endl;
    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/naipp/article/details/52374218
文章标签: codeforces dfs
上一篇codeforces 711C - Coloring Trees
下一篇Codeforces 711E. ZS and The Birthday Paradox
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭