zoukankan      html  css  js  c++  java
  • 洛谷 P4336 黑暗前的幻想乡 —— 容斥+矩阵树定理

    题目:https://www.luogu.org/problemnew/show/P4336

    当作考试题了,然而没想出来,呵呵。

    其实不是二分图完美匹配方案数,而是矩阵树定理+容斥...

    就是先放上所有的边,求生成树个数,但其中可能有的公司的边没有选上,所以减去至少一个公司没选上的,加上两个...

    高斯消元里面可以直接除而不用辗转相除,因为取模可以乘逆元,反倒是辗转相除里不能直接用除法,会减不到0。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    int const xn=20,xm=400,mod=1e9+7;
    int n,m[xn],id[xn][xn],deg[xn][xn],sid[xn][xn],ans,cnt;
    ll a[xn][xn];
    vector<int>vc[xn];
    struct N{int u,v;}ed[xm];
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    ll pw(ll a,int b)
    {
      ll ret=1;
      for(;b;b>>=1,a=(a*a)%mod)if(b&1)ret=(ret*a)%mod;
      return ret;
    }
    int upt(int x){while(x>=mod)x-=mod; while(x<0)x+=mod; return x;}
    int gauss()
    {
      for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)a[i][j]=upt(deg[i][j]-sid[i][j]);
      int fl=1;
      for(int i=1;i<n;i++)
        {
          int t=i;
          for(int j=i+1;j<n;j++)
        if(a[j][i]>a[t][i])t=j;
          if(t!=i)
        {
          fl=-fl;
          for(int j=1;j<n;j++)swap(a[i][j],a[t][j]);
        }
          for(int j=i+1;j<n;j++)
        {
          int tmp=(ll)a[j][i]*pw(a[i][i],mod-2)%mod;//a[j][i]/a[i][i]
          for(int k=i;k<n;k++)
            a[j][k]=upt(a[j][k]-(ll)tmp*a[i][k]%mod);
        }
        }
      ll ret=1;
      for(int i=1;i<n;i++)ret=(ll)ret*a[i][i]%mod;
      return ret*fl;
    }
    void dfs(int nw,int s)
    {
      if(nw==n)
        {
          int sum=gauss();
          if((s&1)==((n-1)&1))ans+=sum; else ans-=sum;
          ans=upt(ans);
          return;
        }
      dfs(nw+1,s); int siz=vc[nw].size();
      for(int i=0;i<siz;i++)
        {
          int u=ed[vc[nw][i]].u,v=ed[vc[nw][i]].v;
          deg[u][u]++; deg[v][v]++;
          sid[u][v]++; sid[v][u]++;
        }
      dfs(nw+1,s+1);
      for(int i=0;i<siz;i++)
        {
          int u=ed[vc[nw][i]].u,v=ed[vc[nw][i]].v;
          deg[u][u]--; deg[v][v]--;
          sid[u][v]--; sid[v][u]--;
        }
    }
    int main()
    {
      n=rd();
      for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
          ed[++cnt].u=i,ed[cnt].v=j,id[i][j]=id[j][i]=cnt;
      for(int i=1;i<n;i++)
        {
          m[i]=rd();
          for(int j=1,x,y;j<=m[i];j++)x=rd(),y=rd(),vc[i].pb(id[x][y]);
        }
      dfs(1,0);
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    Mycat的server.xml配置
    Docker构建Mycat(单节点)
    Mycat相关概念解读
    Mycat简介及适用场景
    SpringBoot整合WebService
    SpringBoot事务简单操作及手动回滚
    对事务及其注解@Transactional的解读
    git将某分支的某次提交合并到另一分支
    SpringBoot快速支持国际化i18n
    SpringBoot多数据源自动切换
  • 原文地址:https://www.cnblogs.com/Zinn/p/10052388.html
Copyright © 2011-2022 走看看