JZOJ 5702. 【gdoi2018 day2】第二题 滑稽子图(subgraph)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liyizhixl/article/details/80323796

Description

Description
Description
Description

Input

Input

Output

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

Data Constraint

Solution

  • 博主懒……先贴题解:

Solution
Solution

  • 考场上没有想到运用二项式定理来优化DP,太弱了……

  • 唯一要注意的是在 xy 都选的时候,它们之间的边也要选,那么边数要加一,

  • 这就相当于合并一个全一的数组(其实就是整体右移一位)。

  • 时间复杂度 O(NK2)

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;
}
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页