道路建造
作者:互联网
Joe是E市的道路局局长,他正在筹划E市的道路建造计划。Joe将E市视为一个包含$n¥个点的图,点之间的边(道路)需要进行建造。他认为一个可行的道路建造方案需要满足以下条件:
将道路视为无向边,整张图无重边无自环
可以通过恰好一次操作使得图中存在一条欧拉回路(从某个点出发经过所有边恰好一次并最终回到起点的路径),其中操作可以是添加一条不在图中的边或是删去一条图中的边。要求操作后图仍满足条件1且图中任意两点可以互相到达。
现在Joe想知道有多少种不同的可行的道路建造方案。两个方案不同当且仅当某条边\((u,v)\)恰好只存在于某一个方案中。
请你帮助Joe,你只需要告诉他答案模\(1000000007(10^9+7)\)的值。
输入格式
仅一行一个整数\(n\)表示图中点的个数。
输出格式
仅一行一个整数表示答案。
样例1
input
3
output
3
样例2
input
9
output
21124449
数据范围
20%的数据:\(n≤10\)
60%的数据:\(n≤100\)
100%的数据:\(2≤n≤2000\)
时间限制:1S
空间限制:256MB
欧拉回路形成的条件是什么?每一个点点度都是偶数并且图联通。我们在图中选第n个点,其他点随便联,如果连完后有一个点,他点度是奇数,就把第n个点和他连边,这样保证了点度全部是偶数。那么n-1个点随便联的方案数是\(2^{C_{n-1}^2}\)
在什么情况会不连通呢?当出现一个联通块没有奇数的点的时候,图不连通。也就是有一个联通块存在欧拉回路的时候,图不连通。我们发现似乎有递推的影子。
避免重复,我们就假设某一个点所在的联通块含有欧拉回路。枚举联通块大小j,联通块有\(f_j\)种可能性,其余的有\(2^{C_{i-j}^2}\)种可能性。那么还要在\(i-1\)个点里面选出联通块除假设的那一个点的\(j-1\)个,答案乘上\(C_{i-1}^{j-1}\)。
#include<cstdio>
const int mod=1e9+7,N=2005;
int n;
long long f[N],g[N],dp[N][N],c[N][N];
long long qumo(long long x)
{
return (x%mod+mod)%mod;
}
int pow(int x,int t)
{
if(t==0)
return 1;
int k=pow(x,t/2);
if(t&1)
return 1LL*k*k%mod*x%mod;
return 1LL*k*k%mod;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
dp[i][0]=dp[i][i]=1;
for(int j=1;j<i;j++)
dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mod;
}
for(int i=1;i<=n;i++)
{
f[i]=g[i]=pow(2,dp[i-1][2]);
for(int j=1;j<i;j++)
{
f[i]=qumo(f[i]-f[j]*g[i-j]%mod*dp[i-1][j-1]%mod);
}
}
printf("%d",(1LL*f[n]*dp[n][2])%mod);
}
标签:联通,个点,int,建造,long,道路,Joe,mod 来源: https://www.cnblogs.com/mekoszc/p/16209958.html