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


    题目大意:给你n个点n条边的有向图,你可以任意地反转一条边的方向,也可以一条都不反转,问你有多少种反转的方法

    使图中没有环。

    思路:我们先把有向边全部变成无向边,每个连通图中肯定有且只有一个环,如果这个连通图里边有n个点,环由m个元素

    构成,那么这个连通图的反转方法数为,(2^(n-m)) * (2^m-2),然后将所有连通图的种数乘到一起就好啦。具体求圆环由几

    个点组成看代码。

    ps:最后算ans的时候忘了加括号,debug了一个小时QAQ。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2*1e5+5;
    const ll mod=1e9+7;
    vector<ll> e[N];
    ll n,pre[N],S,E,cnt,dfn[N],idext,ans;
    ll q_pow(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            a%=mod;
            if(b&1) ans=ans*a%mod;
            b>>=1; a=a*a%mod;
        }
        return ans;
    }
    void dfs(ll v,ll p)
    {
        pre[v]=p; cnt++;
        dfn[v]=++idext;
        for(ll i:e[v])
        {
            if(i==p) continue;
            if(pre[i] && S==-1)
            {
                if(dfn[i]<dfn[v]) E=v,S=i;
                else E=i,S=v;
            }
            if(pre[i]==0) dfs(i,v);
        }
    }
    int main()
    {
        scanf("%lld",&n);
        for(ll i=1;i<=n;i++)
        {
            ll g; scanf("%lld",&g);
            e[g].push_back(i);
            e[i].push_back(g);
        }
        ans=1;
        for(ll i=1;i<=n;i++)
        {
            cnt=0; S=E=-1;
            if(pre[i]==0)
            {
                dfs(i,-1);
                ll num=1;
                while(E!=S)
                {
                    num++;
                    E=pre[E];
                }
                ll res=ans;
                ans=ans*((q_pow(2,cnt-num)*(q_pow(2,num)-2))%mod)%mod;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    序列化
    python_模块与包
    python_常用内置模块
    python_生成器
    python_文件操作
    你好,mysql
    2017年12月20日 内置对象
    2017年12月17日 ASP.NET 12个表单元素&&简单控件/复合控件
    2017年12月16日 ASP.NET基本用法
    2017年12月14日 LinQ高级查&&Asp.net WebForm Asp.net MVC
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7891912.html
Copyright © 2020-2023  润新知