您的位置:首页 > 其它

hdu 4408 最小生成树计数

2013-04-30 19:43 190 查看
经典题了

#include <utility>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <bitset>
#include <map>
#include <iterator>
using namespace std;
#define clr(a,v) memset(a,v,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF = 0x7f7f7f7f;
const int maxn = 211;
const double pi = acos(-1.0);
const double eps = 1e-10;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
typedef pair<int, int> pii;
int deg[maxn][maxn];
ll det[maxn][maxn];
int G[maxn][maxn];
int n, m, p, mod;
vector<pii>::iterator it;
int f[maxn], g[maxn];
int find(int n, int f[]) {
return f
== n ? n : f
= find(f
, f);
}
bool vis[maxn];
ll Det(int n) {
int i, j, k;
ll ans = 1, t;
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
while (det[j][i]) {
t = det[i][i] / det[j][i];
for (k = i; k < n; ++k) {
det[i][k] -= det[j][k] * t;
det[i][k] %= mod;
swap(det[i][k], det[j][k]);
}
ans *= -1;
}
}
if (!det[i][i])
return 0;
}
for (i = 0; i < n; ++i) {
ans = ans * det[i][i] % mod;
}
ans = (ans % mod + mod) % mod;
return ans;
}
int main() {
int i, j, u, v, w;
int p, q;
while (~scanf("%d%d%d", &n, &m, &p) && (n | m | p)) {
mod = p;
memset(G, 0, sizeof(G));
for (i = 0; i < n; ++i)
f[i] = g[i] = i;
vector<pii> V[12];
vector<int> gra[maxn];
for (i = 0; i < m; ++i) {
scanf("%d%d%d", &u, &v, &w);
--u, --v;
V[w].push_back(pii(u, v));
}
if (!m) {
puts("0");
continue;
}
int sz;
ll ans = 1;
memset(vis, false, sizeof(vis));
for (i = 1; i <= 10; ++i) {
if (V[i].empty())
continue;
sz = V[i].size();
for (it = V[i].begin(); it != V[i].end(); ++it) {
u = it->first;
v = it->second;
u = find(u, f);
v = find(v, f);
if (u == v)
continue;
vis[u] = vis[v] = true;
G[u][v]++;
G[v][u]++;
u = find(u, g);
v = find(v, g);
g[u] = v;
}
for (j = 0; j < n; ++j) {
if (!vis[j])
continue;
vis[j] = false;
u = find(j, g);
gra[u].push_back(j);
}
for (j = 0; j < n; ++j) {
if ((int) gra[j].size() > 1) {
sz = gra[j].size();
for (p = 0; p < sz; ++p)
for (q = 0; q < sz; ++q)
det[p][q] = 0;
for (p = 0; p < sz; ++p) {
for (q = p + 1; q < sz; ++q) {
u = gra[j][p];
v = gra[j][q];
det[p][q] = det[q][p] = -G[u][v];
det[p][p] += G[u][v];
det[q][q] += G[v][u];
}
}

ll t = Det(sz - 1);
ans = ans * t % mod;
}
}
for (j = 0; j < n; ++j)
f[j] = g[j] = find(j, g), gra[j].clear();
}
bool flag = true;
for (i = 1; i < n && flag; ++i) {
if (f[i] != f[i - 1]) {
flag = false;
break;
}
}
if (!flag)
ans = 0;
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: