[模板] BEST 定理
一、题目
二、解法
这篇博客主要记录我的感性理解,相信能帮助你直观地理解 定理。
首先对于一条欧拉路径,我们考虑保留每个点的最后一条出边。可以证明出边一定构成一棵内向树,我们只需要证明不会构成环,而如果构成环,考虑走完环的最后一条出边一定会停留在这个点,那么就无法停留在出发点了,这与欧拉路径是矛盾的。
所以我们考虑统计出内向树的个数,那么剩下的边怎么排列呢?发现任意排列都可以构成欧拉路径,所以要乘上 ,那么我们就得到了 定理,设 为内向生成树个数:
本题起点第一条边的选择也是需要考虑的,所以还要在此基础上乘上
使用此定理的条件是存在欧拉路径,我们需要判断每个点入度出度,以及所有的边弱联通。计算行列式的时候对于没有边的点需要忽略(要不然就把 乘进去了)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 105;
const int M = 200005;
const int MOD = 1e6+3;
#define int long long
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int T,n,fac[M],in[N],out[N],fa[N],a[N][N];
int find(int x)
{
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
int qkpow(int a,int b)
{
int r=1;
while(b>0)
{
if(b&1) r=r*a%MOD;
a=a*a%MOD;
b>>=1;
}
return r;
}
int gauss()
{
int ans=1;
for(int i=2;i<=n;i++)
{
for(int j=i;j<=n;j++)
if(!a[i][i] && a[j][i])
{
swap(a[i],a[j]);
ans=MOD-ans;
break;
}
if(out[i]) ans=ans*a[i][i]%MOD;
for(int j=1;j<=n;j++)
{
if(i==j || !a[j][i]) continue;
int t=a[j][i]*qkpow(a[i][i],MOD-2)%MOD;
for(int k=1;k<=n;k++)
a[j][k]=(a[j][k]-t*a[i][k]%MOD+MOD)%MOD;
}
}
return ans;
}
void work()
{
n=read();int fl=1;
memset(a,0,sizeof a);
for(int i=1;i<=n;i++)
fa[i]=i,in[i]=out[i]=0;
for(int i=1;i<=n;i++)
{
int k=read();
while(k--)
{
int j=read();out[i]++;in[j]++;
a[i][i]=(a[i][i]+1)%MOD;
a[i][j]=(a[i][j]+MOD-1)%MOD;
fa[find(i)]=find(j);
}
}
for(int i=1;i<=n;i++)
if(in[i]!=out[i] || (out[i] && find(i)^find(1)))
{puts("0");return ;}
for(int i=1;i<=n;i++) fl&=(out[i]==0);
if(fl) {puts("1");return ;}
int ans=gauss()*out[1]%MOD;
for(int i=1;i<=n;i++)
if(out[i]) ans=ans*fac[out[i]-1]%MOD;
printf("%lld\n",ans);
}
signed main()
{
T=read();fac[0]=1;
for(int i=1;i<=200000;i++)
fac[i]=fac[i-1]*i%MOD;
while(T--) work();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)