UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)
2015-06-24 20:42
465 查看
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=648&page=show_problem&problem=5150
题目大意:给一幅N个点M条边的无向图,有一些边,其中一部分只能涂红色,一部分只能涂黑色,一部分两种颜色都可以涂。现要求红色的边不超过K条的生成树个数模1e9+7的值。
思路:感谢昂神滋磁,贴链接:http://sd-invol.github.io/2015/05/31/Matrix-Tree-Polynomial/
由于不会范德蒙德矩阵,也不会拉格朗日插值,只好乖乖高斯消元了……
代码(0.429S):
View Code
题目大意:给一幅N个点M条边的无向图,有一些边,其中一部分只能涂红色,一部分只能涂黑色,一部分两种颜色都可以涂。现要求红色的边不超过K条的生成树个数模1e9+7的值。
思路:感谢昂神滋磁,贴链接:http://sd-invol.github.io/2015/05/31/Matrix-Tree-Polynomial/
由于不会范德蒙德矩阵,也不会拉格朗日插值,只好乖乖高斯消元了……
代码(0.429S):
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <vector> using namespace std; typedef long long LL; typedef vector<vector<int> > Mat; const int MAXV = 55; const int MAXE = MAXV * MAXV; const int MOD = 1e9 + 7; void debug(const Mat &a) { puts("#debug:"); for(auto &i : a) { for(auto j : i) printf("%d ", j); puts(""); } } int inv(int x) { if(x == 1) return 1; return LL(MOD - MOD / x) * inv(MOD % x) % MOD; } int det(Mat &a, int n) { LL res = 1; for(int i = 1; i < n; ++i) { if(a[i][i] == 0) return 0; for(int j = i + 1; j < n; ++j) { LL t = LL(a[j][i]) * inv(a[i][i]) % MOD; for(int k = i; k < n; ++k) { a[j][k] -= (a[i][k] * t) % MOD; if(a[j][k] < 0) a[j][k] += MOD; } } res = (res * a[i][i]) % MOD; } return res; } void guass(Mat &a, int n) { for(int i = 0; i < n; ++i) { for(int j = i + 1; j < n; ++j) { LL t = LL(a[j][i]) * inv(a[i][i]) % MOD; for(int k = i; k <= n; ++k) { a[j][k] -= (a[i][k] * t) % MOD; if(a[j][k] < 0) a[j][k] += MOD; } } } for(int i = n - 1; i >= 0; --i) { for(int j = i + 1; j < n; ++j) { a[i] -= (LL(a[i][j]) * a[j] ) % MOD; if(a[i] < 0) a[i] += MOD; } a[i] = LL(a[i] ) * inv(a[i][i]) % MOD; } } int la[MAXE], lb[MAXE], kind[MAXE]; int T, n, m, k; int get_column(int a) { Mat mat(n, vector<int>(n)); for(int i = 0; i < m; ++i) { int t = (kind[i] & 1) * a + (kind[i] >> 1); mat[la[i]][la[i]] += t; mat[lb[i]][lb[i]] += t; mat[la[i]][lb[i]] = mat[lb[i]][la[i]] = (t > 0 ? MOD - t : 0); } return det(mat, n); } int solve() { Mat mat(n, vector<int>(n + 1)); for(int i = 0; i < n; ++i) { LL tmp = 1; for(int j = 0; j < n; ++j) mat[i][j] = tmp, tmp = (tmp * i) % MOD; mat[i] = get_column(i); } //debug(mat); guass(mat, n); int res = 0; for(int i = 0; i <= k; ++i) { res += mat[i] ; if(res >= MOD) res -= MOD; } return res; } int main() { scanf("%d", &T); for(int t = 1; t <= T; ++t) { scanf("%d%d%d", &n, &m, &k); for(int i = 0; i < m; ++i) { scanf("%d%d%d", &la[i], &lb[i], &kind[i]); la[i]--, lb[i]--; } printf("Case #%d: %d\n", t, solve()); } }
View Code
相关文章推荐
- Factorial Trailing Zeroes
- 关于类似Gmail邮件撤销功能实现初探
- Leetcode 220 Contains Duplicate III
- NSBundle的使用,注意mainBundle和Custom Bundle的区别
- JetBrain WebStorm 注册码
- leetcode-11Container With Most Water
- Error:Flash Download Failed-"Cortex-M3"
- TrinityCore BossAI
- Thunderbird Mail 支持 Microsoft Exchange
- 地形算法 Fractal Terrain Generation
- RAM check failed @address 0x20000000
- How do I add classes to main menu ul and li in Drupal 8
- ORA-21561: OID generation failed解决
- 修改aix /etc/profile
- TIME_WAIT详解(译)
- 实战DDD(Domain-Driven Design领域驱动设计:Evans DDD)
- container_of
- [转]NDK编译库运行时报dlopen failed: cannot locate symbol "__exidx_end" 解决办法
- Compiler Error Message: The compiler failed with error code 128. 的问题解决
- ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction