Description
Input
Output
Sample Input
Sample Input1
3 2 1
1 2
1 3
Sample Input2
6 5
1 2
1 3
1 4
1 6
4 5
Sample Output
Sample Output1
4
Sample Output2
216
Data Constraint
Solution
- 博主懒……先贴题解:
考场上没有想到运用二项式定理来优化DP,太弱了……
唯一要注意的是在 x x 和 都选的时候,它们之间的边也要选,那么边数要加一,
这就相当于合并一个全一的数组(其实就是整体右移一位)。
时间复杂度 O(NK2) O ( N K 2 ) 。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
const int N=1e5+5,mo=998244353;
typedef long long LL;
int n,m,k,tot;
int first[N],nex[N<<1],en[N<<1];
int f[N][2][11],g[11][11],h[11],one[11];
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline void insert(int x,int y)
{
nex[++tot]=first[x];
first[x]=tot;
en[tot]=y;
}
inline void trans(int *a,int *b)
{
int c[11];
memset(c,0,sizeof(c));
for(int i=0;i<=k;i++)
for(int j=0;j<=i;j++)
c[i]=(c[i]+(LL)a[j]*b[i-j]%mo*g[i][j]%mo)%mo;
for(int i=0;i<=k;i++) a[i]=c[i];
}
void dfs(int x,int y)
{
f[x][0][0]=f[x][1][0]=1;
for(int i=first[x];i;i=nex[i])
{
int to=en[i];
if(to^y)
{
dfs(to,x);
for(int j=0;j<=k;j++) h[j]=(f[to][0][j]+f[to][1][j])%mo;
trans(f[x][0],h);
for(int j=0;j<=k;j++) h[j]=f[to][1][j];
trans(h,one);
for(int j=0;j<=k;j++) h[j]=(h[j]+f[to][0][j])%mo;
trans(f[x][1],h);
}
}
}
int main()
{
freopen("subgraph.in","r",stdin);
freopen("subgraph.out","w",stdout);
n=read(),m=read(),k=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
insert(x,y);
insert(y,x);
}
for(int i=0;i<=k;i++) g[i][0]=1;
for(int i=1;i<=k;i++)
for(int j=1;j<=i;j++) g[i][j]=(g[i-1][j]+g[i-1][j-1])%mo;
for(int i=0;i<=k;i++) one[i]=1;
dfs(1,0);
printf("%d",(f[1][0][k]+f[1][1][k])%mo);
return 0;
}