题意有点绕,读懂题意之后就是一道简单计数状压dp。
大致题意:
给出一幅图,要求计算从起点开始走到终点的(在题目特殊规则下统计的)路径条数。
根据题意,一条路径会被一个复杂的公式分成0路径和1路径两种,而题目则是要求到达终点的opt(opt为已给的0或1)路径有多少。(opt为输入数据)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N= 20 , MOD= 19260817ll ;
int n, m, x, y, c, max_statue;
int a[ N] [ N] , sum[ 1 << N] ;
int ans, f[ 1 << N] [ N] [ 2 ] ;
signed main ( ) {
scanf ( "%lld%lld" , & n, & m) ;
for ( register int i= 1 ; i<= m; ++ i)
{
scanf ( "%lld%lld" , & x, & y) ;
if ( x!= y) a[ x] [ y] ++ , a[ y] [ x] ++ ;
}
scanf ( "%lld" , & c) ;
max_statue= ( 1ll << n) - 1ll ;
for ( register int p= 1 ; p< max_statue; ++ p)
{
for ( register int i= 1 ; i<= n; ++ i) if ( p& ( 1 << ( i- 1 ) ) ) sum[ p] + = i;
sum[ p] & = 1ll ;
}
f[ 1 ] [ 1 ] [ 0 ] = 1ll ;
for ( register int p= 1 ; p< max_statue; ++ p)
for ( register int i= 1 ; i<= n; ++ i)
if ( ! ( p& ( 1ll << ( i- 1ll ) ) ) )
{
for ( register int j= 1 ; j<= n; ++ j)
if ( p& ( 1ll << ( j- 1ll ) ) && a[ j] [ i] )
{
f[ p| ( 1ll << ( i- 1ll ) ) ] [ i] [ ( 0 + i* sum[ p] % 2 ) % 2 ] = ( f[ p| ( 1ll << ( i- 1ll ) ) ] [ i] [ ( 0 + i* sum[ p] % 2 ) % 2 ] + f[ p] [ j] [ 0 ] * a[ j] [ i] ) % MOD;
f[ p| ( 1ll << ( i- 1ll ) ) ] [ i] [ ( 1 + i* sum[ p] % 2 ) % 2 ] = ( f[ p| ( 1ll << ( i- 1ll ) ) ] [ i] [ ( 1 + i* sum[ p] % 2 ) % 2 ] + f[ p] [ j] [ 1 ] * a[ j] [ i] ) % MOD;
}
}
for ( register int p= 1 ; p<= max_statue; ++ p) ans= ( ans+ f[ p] [ n] [ c] ) % MOD;
printf ( "%lld\n" , ans) ;
return 0 ;
}