HDOJ 5498 Tree

来源:互联网 发布:js根据name获取标签 编辑:程序博客网 时间:2024/06/01 09:26

容斥一下然后生成树计数就行了....

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 105;int a[maxn][maxn];LL c[maxn][maxn];int base, n, m, q;int det(int n){    int ans = 1, i, j, k;    bool flag = true;    for (i = 1; i < n; i++)        for (j = 1; j < n; j++) a[i][j] = (a[i][j] + base) % base;    for (i = 1; i < n; i++)    {        for (j = i + 1; j < n; j++)            while (a[j][i])            {                int t = a[i][i] / a[j][i];                for (k = i; k < n; k++) a[i][k] = (a[i][k] + base - (LL)t * (LL)a[j][k] % base) % base;                for (k = i; k < n; k++) swap(a[i][k], a[j][k]);                flag ^= true;            }        ans = (LL)ans * (LL)a[i][i] % base;        if (!ans) return 0;    }    if (!flag) ans = (base - ans);    return ans;}void init(){int N = 100;c[0][0] = 1 % base;for(int i = 1; i <= N; i++) {c[i][0] = 1 % base;for(int j = 1; j <= i; j++)c[i][j] = (c[i-1][j] + c[i-1][j-1]) % base;}}LL powmod(LL a, LL b){LL res = 1, BASE = a;while(b) {if(b % 2) res = res * BASE % base;BASE = BASE * BASE % base;b /= 2;}return res;}void work(){scanf("%d%d%d%d", &n, &m, &base, &q);init();memset(a, 0, sizeof a);for(int i = 1; i <= m; i++) {int u, v;scanf("%d%d", &u, &v);a[u][v]--, a[v][u]--;a[u][u]++, a[v][v]++;}int res = det(n);LL cnt = powmod(n-1, q);for(int i = 1; i <= n-1; i++) {if(i & 1) cnt = (cnt - c[n-1][i] * powmod(n-1-i, q) % base) % base;else cnt = (cnt + c[n-1][i] * powmod(n-1-i, q) % base) % base;}LL ans = cnt * res % base;ans = (ans % base + base) % base;printf("%lld\n", ans);}int main(){//freopen("data", "r", stdin);int _;scanf("%d", &_);while(_--) work();return 0;}


0 0