hdu 4408 Minimum Spanning Tree
生活随笔
收集整理的這篇文章主要介紹了
hdu 4408 Minimum Spanning Tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目連接:點擊打開鏈接
解法:利用kruskal算法 把圖劃分成森林, 同一點有相同最小的權值到別的點, 通過determinant計算樹的課數。
總結:模板 + 自己不太懂 = 記錄 + 重新學
代碼君:
#include <stdio.h> #include <iostream> #include <vector>#define LL long longusing namespace std;const int MAX = 105; const int MAXE = 1005;struct node {int set[MAX];void init(int n){for (int i = 0; i <= n; i++)set[i] = i;}int find(int x){if (set[x] != x)set[x] = find(set[x]);return set[x];}int Union(int x, int y){int xx = find(x);int yy = find(y);if (xx == yy)return -1;set[xx] = yy;return 1;} };struct Node {int u, v, dis; };node a, b, c; int n, m; Node e[MAXE]; int visit[MAX]; vector<int> g[MAX]; LL p[MAX][MAX], MOD, deg[MAX][MAX];bool cmp(Node a, Node b) {return a.dis < b.dis; }LL DET(LL a[][MAX], int n) {LL temp = 1, t;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)a[i][j] %= MOD;for (int i = 1; i < n; i++){for (int j = i + 1; j < n; j++)while (a[j][i]){t = a[i][i] / a[j][i];for (int k = i; k < n; k++){a[i][k] -= a[j][k] * t;a[i][k] %= MOD;}for (int k = i; k < n; k++){t = a[i][k];a[i][k] = a[j][k];a[j][k] = t;}temp = -temp;}temp = temp * a[i][i] % MOD;}return (temp + MOD) % MOD; }LL cal_MST_cout() {sort(e + 1, e + m + 1, cmp);int pre = e[1].dis;LL ans = 1;a.init(n);b.init(n);memset(visit, false, sizeof(visit));memset(deg, false, sizeof(deg));for (int i = 0; i <= n; i++)g[i].clear();for (int t = 1; t <= m + 1; t++){if (e[t].dis != pre || t == m + 1){for (int i = 1; i <= n; i++)if (visit[i]){int k = b.find(i);g[k].push_back(i);visit[i] = 0;}for (int i = 1; i <= n; i++)if (g[i].size()){memset(p, false, sizeof(p));for (int j = 0; j < g[i].size(); j++)for (int k = j + 1; k < g[i].size(); k++){int x = g[i][j];int y = g[i][k];p[j][k] = p[k][j] = -deg[x][y];p[j][j] += deg[x][y];p[k][k] += deg[x][y];}ans = ans * DET(p, g[i].size()) % MOD;for (int j = 0; j < g[i].size(); j++)a.set[g[i][j]] = i;}memset(deg, false, sizeof(deg));for (int i = 1; i <= n; i++){b.set[i] = a.find(i);g[i].clear();}if (t == m + 1)break;pre = e[t].dis;}int x = a.find(e[t].u);int y = a.find(e[t].v);if (x == y)continue;visit[x] = visit[y] = 1;b.Union(x, y);deg[x][y]++;deg[y][x]++;}if (!m)return false;for (int i = 2; i <= n; i++)if (b.find(i) != b.find(1))return false;return ans; }int main() {while (~scanf("%d%d%lld", &n, &m, &MOD) && (n | m | MOD)){for (int i = 1; i <= m; i++)scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].dis);printf("%lld\n", cal_MST_cout());} }總結
以上是生活随笔為你收集整理的hdu 4408 Minimum Spanning Tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机系统在线帮助,FoxPro应用系统
- 下一篇: 人工智能教程(1.1)