记录编号 |
143608 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[国家集训队2011]连边 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.569 s |
提交时间 |
2014-12-16 14:01:39 |
内存使用 |
15.88 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int SIZEN=1010;
const LL MOD=10007;
LL C[SIZEN][SIZEN];
int N,M,K;
int deg[SIZEN],evennum=0,oddnum=0,all;
LL f[SIZEN][SIZEN];//i个奇数,j次
void prepare_C(void){
for(int i=0;i<SIZEN;i++){
C[i][0]=C[i][i]=1;
for(int j=1;j<=i;j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
}
}
LL quickpow(LL a,LL n){
LL ans=1;
while(n){
if(n&1) ans=(ans*a)%MOD;
a=(a*a)%MOD;
n>>=1;
}
return ans;
}
LL inverse(LL a){
return quickpow(a,MOD-2);
}
LL fact(LL n){
LL ans=1;
for(int i=1;i<=n;i++) ans=(ans*i)%MOD;
return ans;
}
void answer(void){
LL ans=f[oddnum][K];
ans=ans*inverse(fact(K))%MOD;
printf("%lld\n",ans);
}
void DP(void){
f[0][0]=1;
for(int j=1;j<=K;j++){
for(int i=0;i<=N;i++){//i个奇数,j次
//情况1:一奇一偶
if(i>=1&&N-i>=1){
f[i][j]+=(f[i][j-1]*i*(N-i))%MOD;
f[i][j]%=MOD;
}
//情况2:两奇
if(i>=2){
f[i][j]+=(f[i-2][j-1]*C[i][2])%MOD;
f[i][j]%=MOD;
}
//情况3:两偶
if(N-i>=2){
f[i][j]+=(f[i+2][j-1]*C[N-i][2])%MOD;
f[i][j]%=MOD;
}
if(j>=2){
f[i][j]-=(all-(j-2))*(j-1)*f[i][j-2];
f[i][j]%=MOD;
if(f[i][j]<0) f[i][j]+=MOD;
}
}
}
}
void read(void){
scanf("%d%d%d",&N,&M,&K);
all=N*(N-1)/2;
int a,b;
for(int i=1;i<=M;i++){
scanf("%d%d",&a,&b);
deg[a]++;deg[b]++;
}
for(int i=1;i<=N;i++){
if(deg[i]&1) oddnum++;
else evennum++;
}
}
int main(){
freopen("nt2011_edges.in","r",stdin);
freopen("nt2011_edges.out","w",stdout);
prepare_C();
read();
DP();
answer();
return 0;
}