题目链接: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):

 #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 = ;
const int MAXE = MAXV * MAXV;
const int MOD = 1e9 + ; 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 == ) return ;
return LL(MOD - MOD / x) * inv(MOD % x) % MOD;
} int det(Mat &a, int n) {
LL res = ;
for(int i = ; i < n; ++i) {
if(a[i][i] == ) return ;
for(int j = i + ; 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] < ) a[j][k] += MOD;
}
}
res = (res * a[i][i]) % MOD;
}
return res;
} void guass(Mat &a, int n) {
for(int i = ; i < n; ++i) {
for(int j = i + ; 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] < ) a[j][k] += MOD;
}
}
}
for(int i = n - ; i >= ; --i) {
for(int j = i + ; j < n; ++j) {
a[i][n] -= (LL(a[i][j]) * a[j][n]) % MOD;
if(a[i][n] < ) a[i][n] += MOD;
}
a[i][n] = LL(a[i][n]) * 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 = ; i < m; ++i) {
int t = (kind[i] & ) * a + (kind[i] >> );
mat[la[i]][la[i]] += t;
mat[lb[i]][lb[i]] += t;
mat[la[i]][lb[i]] = mat[lb[i]][la[i]] = (t > ? MOD - t : );
}
return det(mat, n);
} int solve() {
Mat mat(n, vector<int>(n + ));
for(int i = ; i < n; ++i) {
LL tmp = ;
for(int j = ; j < n; ++j)
mat[i][j] = tmp, tmp = (tmp * i) % MOD;
mat[i][n] = get_column(i);
}
//debug(mat);
guass(mat, n); int res = ;
for(int i = ; i <= k; ++i) {
res += mat[i][n];
if(res >= MOD) res -= MOD;
}
return res;
} int main() {
scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d%d%d", &n, &m, &k);
for(int i = ; i < m; ++i) {
scanf("%d%d%d", &la[i], &lb[i], &kind[i]);
la[i]--, lb[i]--;
}
printf("Case #%d: %d\n", t, solve());
}
}

最新文章

  1. java ---- 面试题
  2. beetle.express针对websocket的高性能处理
  3. 【BZOJ-1853&amp;2393】幸运数字&amp;Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝
  4. Android学习笔记——menu
  5. Web前端开发:什么是页面重回(repaints)与回流(reflow)
  6. 在Linux上运行C#
  7. 0703-APP-Notification-statue-bar
  8. iOS开发中常用到的加密方式
  9. Mysql 配置慢查询日志(SlowQueryLog)以及使用日志分析工具
  10. N沟道增强型MOS管双向低频开关电路
  11. 《OpenCV3 计算机视觉--Python语言实现 第二版》源代码及纠错
  12. 你不可不知的Java引用类型之——Reference源码解析
  13. 表table
  14. 深入分析Zookeeper的实现原理
  15. oracle 之 基础操作
  16. Heapify
  17. DragonBones龙骨插槽的隐藏
  18. 洛谷4030(Codeplus11月月赛)可做题1
  19. Ofstream的endl不好用怎么回事?
  20. javascript+html5+css3下拉刷新 数据效果

热门文章

  1. zorka源码解读之tracer内部实现
  2. PHP文件上传
  3. java并发编程(六)Runnable和Thread实现多线程的区别
  4. JS创建缩略图
  5. 用Java实现简单的web服务器
  6. Invoke-Command和-ComputerName 效率比较
  7. php变量和数组大小限制
  8. monkey命令
  9. completionService
  10. php 读取文件