test20200430 最长路径

最长路径

在Byteland一共有\(n\)个城市,编号依次为\(1\)\(n\),它们之间计划修建\(\binom{n}{2}\)条单向道路,对于任意两个不同的点\(i\)\(j\),在它们之间有且仅有一条单向道路,方向要么是\(i\)\(j\),要么是\(j\)\(i\)。换句话说,这是一个\(n\)个点的竞赛图。

Byteasar居住在\(1\)号城市,他希望从\(1\)号城市出发,沿着单向道路不重复地访问一些城市,使得访问的城市数尽可能多。

请写一个程序,帮助Byteasar计算有多少种道路修建方式,使得从\(1\)号点出发的最长简单路径经过点数恰好为\(k\),由于答案可能很大,请对\(P\)取模输出。

题解

竞赛图一定存在哈密顿路径。

对于\(n\)个点的竞赛图,\(1\)号点能作为哈密顿路径起点的充要条件是\(1\)能到剩余\(n-1\)个点。

考虑归纳证明,\(n=1,2\)时显然成立。对于\(n\geq 3\)的情况,显然\(1\)能到剩余\(n-1\)个点是必要的,不然何谈哈密顿路径。证明充分性考虑构造,我们\(1\)至少能到剩余\(n-1\)个点导出子图的所有哈密顿路径的起点中至少一个,不然与假设矛盾。证毕。

所以这道题要让最长路为\(k\)只需要让\(1\)能到\(k\)个点,其余\(n-k\)个点不能到即可。

\(f_n\)\(1\)能作为哈密顿路径起点的\(n\)个点的竞赛图数量,\(g_n=2^{\binom{n}{2}}\)

\[f_n=g_n-\sum_{i=1}^{n-1}\binom{n-1}{i-1}f_ig_{n-i} \]

最后有\(\text{ans}_k=\binom{n-1}{k-1}f_kg_{n-k}\)。时间复杂度\(O(n^2)\)

CO int N=2e3+10;
int C[N][N],G[N],F[N];

int main(){
	int n=read<int>(),P=read<int>();
	for(int i=0;i<=n;++i){
		C[i][0]=1;
		for(int j=1;j<=i;++j) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
	}
	for(int i=0;i<=n;++i) G[i]=fpow(2,i*(i-1)/2,P);
	for(int i=1;i<=n;++i){
		F[i]=G[i];
		for(int j=1;j<=i-1;++j) F[i]=(F[i]+P-(int64)C[i-1][j-1]*F[j]%P*G[i-j]%P)%P;
	}
	for(int i=1;i<=n;++i){
		int ans=(int64)C[n-1][i-1]*F[i]%P*G[n-i]%P;
		printf("%d\n",ans);
	}
	return 0;
}

然后是老生常谈的生成函数优化。其实这个式子跟有标号连通无向图的一模一样。

\[F'=G'-F‘(G-1) \]

\[F'=\frac{G'}{G} \]

\[F=\ln G\leftrightarrow G=e^F \]

时间复杂度\(O(n\log n)\)

posted on 2020-05-06 07:56  autoint  阅读(168)  评论(0编辑  收藏  举报

导航