1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "queue" using namespace std; #define MAXN 46
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) typedef long long ll; #define P 1000000007 int n , m , x , y; int G[3][MAXN][MAXN] , deg[3][MAXN]; int g[MAXN * MAXN] , f[MAXN * MAXN] , h[MAXN * MAXN];
inline int Pow( int x , int a ) { int ret = 1; while( a ) { if( a & 1 ) ret = 1ll * ret * x % P; x = 1ll * x * x % P , a >>= 1; } return ret; }
int F[MAXN][MAXN];
inline int lsj( ) { int t = n - 1; int ans = 1; rep( i , 1 , t ) { int cur = -1; rep( j , i , t ) if( F[j][i] ) { cur = j; break; } if( cur == -1 ) continue; if( cur != i ) swap( F[cur] , F[i] ) , ans = -ans; rep( j , i + 1 , t ) { int r = F[j][i] * 1ll * Pow( F[i][i] , P - 2 ) % P; rep( k , 1 , t ) F[j][k] = ( F[j][k] + P - 1ll * r * F[i][k] % P ) % P; } } rep( i , 1 , t ) ans = 1ll * ans * F[i][i] % P; return ans; }
inline int work( int t ) { mem( F ); int qb = t , ql = Pow( t , n ); for( int i = 1 ; i <= n ; ++ i ) F[i][i] = ( F[i][i] + deg[0][i] ) % P , F[i][i] = ( F[i][i] + deg[1][i] * 1ll * qb % P ) % P , F[i][i] = ( F[i][i] + deg[2][i] * 1ll * ql % P ) % P ; for( int i = 1 ; i <= n ; ++ i ) for( int j = 1 ; j <= n ; ++ j ) F[i][j] = ( F[i][j] + P - G[0][i][j] ) % P , F[i][j] = ( F[i][j] + 1ll * ( P - G[1][i][j] ) * qb ) % P , F[i][j] = ( F[i][j] + 1ll * ( P - G[2][i][j] ) * ql ) % P ; return lsj( ); }
void solve() { cin >> n >> m >> x >> y; int u , v , w; rep( i , 1 , m ) { scanf("%d%d%d",&u,&v,&w) , -- w; if( u == v ) continue; ++ G[w][u][v] , ++ G[w][v][u]; ++ deg[w][u] , ++ deg[w][v]; } g[0] = 1; int tot = n * ( n - 1 ); for( int i = 0 ; i <= tot ; ++ i ) for( int j = i ; j >= 0 ; -- j ) ( g[j + 1] += g[j] ) %= P , g[j] = ( P - 1ll * g[j] * i % P ) % P; for( int i = 0 ; i <= tot ; ++ i ) { int pr = work( i ); rep( j , 0 , tot ) if( i != j ) pr = pr * 1ll * ( i < j ? P - Pow( j - i , P - 2 ) : Pow( i - j , P - 2 ) ) % P; rep( j , 0 , tot + 1 ) h[j] = g[j]; per( j , tot + 1 , 1 ) h[j - 1] = ( h[j - 1] + h[j] * 1ll * i % P ) % P; rep( j , 0 , tot ) f[j] = ( f[j] + h[j + 1] * 1ll * pr % P ) % P; } int res = 0; rep( i , 0 , tot ) if( i % n <= x && i / n <= y ) res = ( res + f[i] ) % P; cout << res << endl; }
signed main() {
solve(); }
|