码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵生成树

时间:2017-01-06 15:24:52      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:states   color   eof   opera   生成树   connected   orm   out   lld   

对于每条连边i->j,a[i][j]--,a[i]++

对无向图有向图同时成立

求矩阵det即可

--------------------

BZOJ3659

wikipeida:

We denote these in- and out-degree of a vertex v by deg(v).

The BEST theorem states that the number ec(G) of Eulerian circuits in a connected Eulerian graph G is given by the formula

技术分享

将结果乘上根节点出度即可

#include <cstdio>
#define LL long long 
 
  const LL mo=1000003;
 
  LL a[101][101],fac[200001],num[101];
 
  LL qpow(LL bas,int powe){
      LL ret=1;
      for (;powe;bas*=bas,bas%=mo){
        if (powe&1) ret*=bas,ret%=mo;
      powe=powe>>1;    
    }
    return(ret);
  }
 
  LL work(int n){
    for (int i=1;i<=n;i++){
      for (int j=i+1;j<=n;j++){
          LL bas=a[j][i]*qpow(a[i][i],mo-2)%mo;
          for (int k=i;k<=n;k++)
            a[j][k]-=a[i][k]*bas%mo,a[j][k]%=mo,a[j][k]+=mo,a[j][k]%=mo;
      }    
    }
    LL ret=1;
    for (int i=1;i<n;i++) ret*=a[i][i],ret%=mo;
    return(ret);
  }
  
  int main(){
      fac[0]=1;
      for (int i=1;i<=200000;i++) fac[i]=fac[i-1]*i%mo;
      int n;
      while (scanf("%d",&n)!=EOF,n!=0){
         for (int i=1;i<=n;i++)
       for (int j=1;j<=n;j++)
         a[i][j]=0;
      for (int i=1;i<=n;i++){
          scanf("%d",&num[i]);
          for (int j=1;j<=num[i];j++){
            int tt;
            scanf("%d",&tt);
          a[i][tt]--;a[i][i]++;
        }
      }
      for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]%=mo,a[i][j]+=mo,a[i][j]%=mo;
      LL ans=1;
      for (int i=1;i<=n;i++) ans*=fac[num[i]-1],ans%=mo;
      ans*=work(n);ans%=mo;
      ans*=num[1];ans%=mo;
      printf("%lld\n",ans);
    }
  } 

 

矩阵生成树

标签:states   color   eof   opera   生成树   connected   orm   out   lld   

原文地址:http://www.cnblogs.com/zhujiangning/p/6256255.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!