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 110 111 112 113 114 115 116 117 118 119
| #include <iostream> #include <algorithm> #include <string.h> #include <vector> using namespace std; const int maxn = 105; #define ll long long struct edge { int u, v, w; bool operator<(const edge& temp)const { return w < temp.w; } } edges[1005];
ll B[maxn][maxn], G[maxn][maxn]; int n, m, mod; int pre[maxn], U[maxn]; bool vis[maxn]; vector<int> e[maxn];
ll determina(int n) { ll res = 1; for (int i = 1; i <= n; i++) { if (!B[i][i]) { bool flag = false; for (int j = i + 1; j <= n; j++) { if (B[j][i]) { flag = 1; for (int k = i; k <= n; k++) swap(B[i][k], B[j][k]); res = -res; break; } } if (!flag) return 0; } for (int j = i + 1; j <= n; j++) { while (B[j][i]) { ll t = B[i][i] / B[j][i]; for (int k = i; k <= n; k++) { B[i][k] = (B[i][k] - t * B[j][k]) % mod; swap(B[i][k], B[j][k]); } res = -res; } } res *= B[i][i]; res %= mod; } return (res + mod) % mod; }
int find(int x, int* p) { if (x == p[x]) return x; else return p[x] = find(p[x], p); } void kruskal() { sort(edges, edges + m); for (int i = 1; i <= n; i++) pre[i] = i; memset(vis, 0, sizeof vis); ll tempedge = -1; ll ans = 1; for (int k = 0; k <= m; k++) { if (edges[k].w != tempedge || k == m) { for (int i = 1; i <= n; i++) { if (vis[i]) { int u = find(i, U); e[u].push_back(i); vis[i] = 0; } } for (int i = 1; i <= n; i++) { if (e[i].size() > 1) { memset(B, 0, sizeof B); int len = e[i].size(); for (int a = 0; a < len; a++) for (int b = a + 1; b < len; b++) { int a1 = e[i][a], b1 = e[i][b]; B[a][b] = (B[b][a] -= G[a1][b1]); B[a][a] += G[a1][b1]; B[b][b] += G[a1][b1]; } ll res = determina(len - 1); ans = (ans * res) % mod; for (int a = 0; a < len; a++) pre[e[i][a]] = i; } } for (int i = 1; i <= n; i++) { U[i] = find(i, pre); e[i].clear(); } if (k == m) break; tempedge = edges[k].w; } int a = edges[k].u, b = edges[k].v; int a1 = find(a, pre), b1 = find(b, pre); if (a1 == b1) continue; vis[a1] = vis[b1] = 1; U[find(a1, U)] = find(b1, U); G[a1][b1]++; G[b1][a1]++; } int flag = 0; for (int i = 2; i <= n && !flag; i++) if (U[i] != U[i - 1]) flag = 1; if (m == 0) flag = 1; printf("%lld\n", flag ? 0 : ans % mod); return; } int main() { while (scanf("%d%d%d", &n, &m, &mod) && (n + m + mod)) { memset(G, 0, sizeof G); for (int i = 0; i < m; i++) scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w); kruskal(); for (int i = 1; i <= n; i++) e[i].clear(); } return 0; }
|