51nod 1833 状压dp加一点图论

dp[i][j]:i代表前i个单位,j代表匹配的方案;

#include<stdio.h>
#include<iostream>
#include<vector>
#include<string.h>
#define ll long long
#define MST(vis,x) memset(vis,x,sizeof(vis))
#define maxn 21
#define mod 998244353
using namespace std;
int dp[maxn][(1<<20)+1];
vector<int>vec[22];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int a=1;a<=n;a++)vec[a].clear();
        for(int a=1;a<=m;a++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            vec[x].push_back(y);
        }
        dp[0][0]=1;
        for(int i=1;i<=n;i++)//代表前i个
        {
            for(int j=0;j<vec[i].size();j++)//枚举i与可匹配的数的匹配(用son代表)
            {
                for(int k=1;k<=(1<<n);k++)//枚举匹配模式
                {
                    if((k&(1<<vec[i][j]-1))&&dp[i-1][k-(1<<vec[i][j]-1)])//当匹配模式中有son时&&排除掉这个son和i,剩余的i-1个点在[k-(1<<son-1)]模式下是否有解
                        dp[i][k]=(dp[i][k]+dp[i-1][k-(1<<vec[i][j]-1)])%mod;//如果有解加起来即可
                }
            }
        }
        printf("%d\n",dp[n][(1<<n)-1]);//输出前N个点在最大模式匹配下的结果
}
return 0; }

 

posted @ 2018-03-12 16:32  被咬过的馒头  阅读(128)  评论(0编辑  收藏  举报