zoukankan      html  css  js  c++  java
  • [BZOJ3659]Which Dreamed It

    [BZOJ3659]Which Dreamed It

    题目大意:

    一个(n(nle100))个点,(m(mle2 imes10^5))条边的有向图,求以(1)为起点的欧拉回路数目。

    思路:

    根据BEST定理,有:

    [mathrm{ec}(G)=t_w(G)prodlimits_{vin V}left(deg(v)-1 ight)! ]

    其中,(mathrm{ec}(G))表示图(G)欧拉回路的数目,(t_w(G))表示图(G)中以点(w)为根的内向生成树个数,(deg(v))表示点(v)的出度或入度。

    使用矩阵树定理计算(t_1(G))后直接套用BEST定理即可。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=101,mod=1e6+3;
    int n,in[N],out[N],w[N][N];
    void exgcd(const int &a,const int &b,int &x,int &y) {
    	if(!b) {
    		x=1,y=0;
    		return;
    	}
    	exgcd(b,a%b,y,x);
    	y-=a/b*x;
    }
    inline int inv(const int &x) {
    	int ret,tmp;
    	exgcd(x,mod,ret,tmp);
    	return (ret%mod+mod)%mod;
    }
    inline int matrix_tree() {
    	const int n=::n-1;
    	for(register int i=1;i<=n;i++) {
    		for(register int j=1;j<=n;j++) {
    			w[i][j]=(w[i+1][j+1]%mod+mod)%mod;
    		}
    	}
    	int ans=1;
    	for(register int i=1;i<=n;i++) {
    		int p=0;
    		for(register int j=i;j<=n;j++) {
    			if(w[i][j]) p=j;
    		}
    		if(!p) return 0;
    		if(p!=i) {
    			ans=(mod-ans)%mod;
    			for(register int j=1;j<=n;j++) {
    				std::swap(w[j][i],w[j][p]);
    			}
    		}
    		const int t=inv(w[i][i]);
    		ans=1ll*ans*w[i][i]%mod;
    		for(register int j=i;j<=n;j++) {
    			w[i][j]=1ll*w[i][j]*t%mod;
    		}
    		for(register int j=i+1;j<=n;j++) {
    			const int t=w[j][i];
    			 for(register int k=i;k<=n;k++) {
    			 	((w[j][k]-=1ll*w[i][k]*t%mod)+=mod)%=mod;
    			 }
    		}
    	}
    	return ans;
    }
    int main() {
    	for(;;) {
    		n=getint();
    		if(n==0) return 0;
    		std::fill(&in[1],&in[n]+1,0);
    		for(register int i=1;i<=n;i++) {
    			std::fill(&w[i][1],&w[i][n+1],0);
    		}
    		for(register int i=1;i<=n;i++) {
    			out[i]=getint();
    			for(register int j=0;j<out[i];j++) {
    				const int x=getint();
    				w[i][x]--;
    				in[x]++;
    			}
    		}
    		if(n==1) {
    			int ans=1;
    			for(register int i=1;i<=out[1];i++) {
    				ans=1ll*ans%mod;
    			}
    			printf("%d
    ",ans);
    			continue;
    		}
    		for(register int i=1;i<=n;i++) {
    			w[i][i]+=in[i];
    		}
    		int ans=matrix_tree();
    		for(register int i=1;i<=n;i++) {
    			for(register int j=1;j<out[i];j++) {
    				ans=1ll*ans*j%mod;
    			}
    		}
    		ans=1ll*ans*out[1]%mod;
    		printf("%d
    ",ans);
    	}
    }
    
  • 相关阅读:
    Nginx作为缓存服务
    Nginx作为代理服务
    ZipUtils zip压缩实现
    getman九桃小说解析油猴脚本
    maven添加代理加速jar包下载
    ffmpeg MP3 flv 视频转mp3
    ActiveMQ配置用户认证信息
    JS实现HTML标签转义及反转义
    删除registry镜像数据,以centos为例
    启动一个带登录账号密码的registry容器
  • 原文地址:https://www.cnblogs.com/skylee03/p/10150343.html
Copyright © 2011-2022 走看看