• 有向图欧拉回路个数 BEST定理


    有向图欧拉回路个数

    BZOJ 3659 但是没有这道题了  直接贴一个别人的板子吧

    欧拉回路:存在一条路径经过所有的边刚好1次

    有向图欧拉回路存在充要条件:①图连通;②对于所有点都满足出度=入度

    BEST 定理   https://en.wikipedia.org/wiki/BEST_theorem

    定理没仔细看 这个东西感觉不需要搞得非常懂 定理而已。

    我只记住了公式 tw(G)表示外向生成树个数,deg表示入度出度都一样 相等的嘛。

    当然欧拉回路因为是回路所以存在循环同构,例如下图:

    1->2;2->1;1->3;3->1

    欧拉回路其实只有1种,但是如果算路径走法的话就会有2种

    1 2 1 3 1 和 1 3 1 2 1

    这个时候sum还要再乘上x点的出度

    https://blog.csdn.net/popoqqq/article/details/77017325

    https://blog.csdn.net/Jaihk662/article/details/79338437

    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define LL long long
    #define mod 1000003
    LL Jz[105][105], out[105], jc[200005] = {1};
    int main(void)
    {
        LL ans, A, B, P, temp;
        int n, i, j, k, m, x;
        for(i=1;i<=200000;i++)
            jc[i] = jc[i-1]*i%mod;
        while(scanf("%d", &n), n!=0)
        {
            memset(Jz, 0, sizeof(Jz));
            for(i=1;i<=n;i++)
            {
                scanf("%d", &m);
                out[i] = m;
                while(m--)
                {
                    scanf("%d", &x);
                    Jz[i][x]--, Jz[x][x]++;
                }
            }
            if(n==1 && out[1]==0)
            {
                printf("1
    ");
                continue;
            }
            n -= 1;
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=n;j++)
                    Jz[i][j] = (Jz[i+1][j+1]+mod)%mod;
            }
            ans = 1;
            for(i=1;i<=n;i++)
            {
                for(j=i;j<=n;j++)
                {
                    if(Jz[j][i])
                        break;
                }
                if(j!=i)
                {
                    ans = mod-ans;
                    for(k=i;k<=n;k++)
                        swap(Jz[i][k], Jz[j][k]);
                }
                for(j=i+1;j<=n;j++)
                {
                    A = Jz[i][i], B = Jz[j][i];
                    while(B)
                    {
                        P = A/B, temp = A, A = B, B = temp%B;
                        ans = mod-ans;
                        for(k=i;k<=n;k++)
                        {
                            Jz[i][k] = (Jz[i][k]-P*Jz[j][k]%mod+mod)%mod;
                            swap(Jz[i][k], Jz[j][k]);
                        }
                    }
                }
                ans = ans*Jz[i][i]%mod;
            }
            if(ans==0)
            {
                printf("0
    ");
                continue;
            }
            n += 1;
            for(i=1;i<=n;i++)
                ans = ans*jc[out[i]-1]%mod;
            ans = ans*out[1]%mod;
            printf("%lld
    ", ans);
        }
        return 0;
    }
    /*
    3
    2 2 3
    1 1
    1 1
    */
  • 相关阅读:
    qemu-kvm虚拟化——内存
    Virtualization and Performance: Understanding VM Exits
    Linux日志文件
    Linux那些让你虎躯一震的命令
    Linux命令——watch
    Linux kernel buffer ring
    Linux命令——dmesg
    Linux命令——systemctl
    Linux命令——taskset
    /sys 和 /dev 区别
  • 原文地址:https://www.cnblogs.com/stranger-/p/9544312.html
Copyright © 2020-2023  润新知