【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1016

【题意】

【题解】

/*
接上一篇文章;
这里用matrix-tree定理搞最小生成树个数;
对于每一种相同边权的边;
当做一个阶段;
这个阶段,我们需要看看这个边权的边能连接哪些联通块;
这里的联通块可以缩为一个点;
这样就相当于在一些点中间插入边;
然后问你这些边能够生成的生成树的个数;
即每个阶段都做一遍matrix-tree定理;
martrix-treee定理想要做的话;
你得先得出一张图,最好弄出它的邻接矩阵;
然后可以这样吧。
把这张图缩点之后的节点都标成新的节点;
然后根据新添加进来的边;
建立一张新的图,
然后在这张新图上求生成树;
根据前一篇的分析可知这样的生成树一定是最小生成树的一部分;
建立新图的话也不会难吧;
如果节点之前没出现过就递增节点就好;
然后统计这张新图里面节点的个数;
然后处理出邻接矩阵和度数就能搞了;
不过这样处理会有重边的哦;
当然这个定理也能处理有重边的情况,所以不慌.
每次把生成树的个数根据乘法原则乘到答案上就好
(新的图上可能会有多个连通块,要每个连通块分别算,不然整张图都不是联通的,你再用
整张图去求的话会出错)
(初始化什么的一定要认真检查啊);
(这个行列式的求法不要用double类,不然精度不够,用int。。不知道为什么可以用int..)
*/

推荐一个题解吧

http://www.cnblogs.com/flipped/p/5769228.html

要记住是度数矩阵减去邻接矩阵啊.



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x) typedef pair<int, int> pii;
typedef pair<LL, LL> pll; const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 110;
const int M = 1e3 + 100;
const int MOD = 31011; struct abc
{
int x, y, z;
}; int n, m,tot,cnt = 0;
int f[N],D[N][N],A[N][N],C[N][N],ka[N],g[N][N];
int bo[N];
abc bian[M];
double a[N][N];
vector <int> v[N];
long long ans = 1; bool cmp1(abc a, abc b)
{
return a.z < b.z;
} int ff(int x)
{
if (f[x] == x) return x;
else
return f[x] = ff(f[x]);
} int fk(int x)
{
if (ka[x] == x) return x;
else
return ka[x] = fk(ka[x]);
} int cl(int c[N][N], int n) {
int i, j, k, t, ret = 1;
for (i = 1; i<=n-1; i++) {
for (j = i + 1; j<=n-1; j++)
while (c[j][i]) {
t = c[i][i] / c[j][i];
for (k = i; k<n; k++)
c[i][k] = (c[i][k] - c[j][k] * t) % MOD;
swap(c[i], c[j]);
ret = -ret;
}
if (c[i][i] == 0)
return 0;
ret = ret*c[i][i] % MOD;
}
return (ret + MOD) % MOD;
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
rei(n), rei(m);
rep1(i, 1, m)
rei(bian[i].x), rei(bian[i].y), rei(bian[i].z);
sort(bian + 1, bian + 1 + m,cmp1);
ans = 1;
rep1(i, 1, n)
f[i] = i,ka[i] = i;
rep1(i, 1, m)
{
int l = i, r = i;
while (r + 1 <= m && bian[r + 1].z == bian[l].z) r++;
rep1(j, 1, n)
rep1(jj, 1, n)
g[j][jj] = 0;
rep1(j, 1, n)
bo[j] = 0;
rep1(j, l, r)
{
int x = bian[j].x, y = bian[j].y;
int r1 = ff(x), r2 = ff(y);
if (r1 != r2)
{
int rr1 = fk(r1), rr2 = fk(r2);
if (rr1 != rr2)
ka[rr1] = rr2;
bo[r1] = true, bo[r2] = true;
g[r1][r2]++, g[r2][r1]++;
}
}
rep1(j, 1, n)
v[j].clear();
rep1(j, 1, n)
if (bo[j])
v[fk(j)].push_back(j); rep1(j,1,n)
if (int(v[j].size()) > 1)
{
rep1(k, 1, n)
rep1(kk, 1, n)
D[k][kk] = A[k][kk] = 0;
int len = v[j].size();
rep1(k,0,len-2)
rep1(l, k + 1, len - 1)
{
int x = v[j][k], y = v[j][l];
if (g[x][y])
{
D[k+1][k+1] += g[x][y], D[l+1][l+1] += g[x][y];
A[l+1][k+1] = A[k+1][l+1] = g[x][y];
}
}
rep1(k, 1,len )
rep1(kk, 1, len)
C[k][kk] = D[k][kk] - A[k][kk];
tot = len;
ans = (ans*cl(C,len)) % MOD;
}
rep1(j, l, r)
{
int x = bian[j].x, y = bian[j].y;
int r1 = ff(x), r2 = ff(y);
if (r1 != r2)
{
f[r1] = r2;
cnt++;
}
}
rep1(j, 1, n)
ka[j] = f[j];
i = r;
}
if (cnt != n - 1)
return puts("0"),0;
printf("%lld\n", ans);
return 0;
}

【BZOJ 1016】 [JSOI2008]最小生成树计数(matrix-tree定理做法)的更多相关文章

  1. BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)

    题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...

  2. bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...

  3. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )

    不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...

  4. [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

    题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...

  5. [BZOJ]1016 JSOI2008 最小生成树计数

    最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...

  6. BZOJ 1016 [JSOI2008]最小生成树计数 ——Matrix-Tree定理

    考虑从小往大加边,然后把所有联通块的生成树个数计算出来. 然后把他们缩成一个点,继续添加下一组. 最后乘法原理即可. 写起来很恶心 #include <queue> #include &l ...

  7. bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】

    有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...

  8. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

    1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...

  9. 1016: [JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6200  Solved: 2518[Submit][St ...

  10. @总结 - 7@ 生成树计数 —— matrix - tree 定理(矩阵树定理)与 prüfer 序列

    目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 矩阵树定理主体@ @证明 part - 1@ @证明 part - 2@ @证明 part - 3@ @证明 part ...

随机推荐

  1. Docker---(9)Docker中容器无法停止无法删除

    原文:Docker---(9)Docker中容器无法停止无法删除 版权声明:欢迎转载,请标明出处,如有问题,欢迎指正!谢谢!微信:w1186355422 https://blog.csdn.net/w ...

  2. 双向链表(自己写的c++类)

    UVA还是上不去T T哭瞎了. 只好老老实实的研究上回买的书了. 写得有点长.好吧,我只是来复习C++类的. 特意用class 而不用struct写链表. 数据结构还没学...双向链表就当先预习了. ...

  3. [D3] Better Code Organization with selection.call() with D3 v4

    Most of D3’s native selection APIs also return the selection (or a new selection), to enable multipl ...

  4. 去哪网实习总结:用到的easyui组件总结(JavaWeb)

    本来是以做数据挖掘的目的进去哪网的,结构却成了系统开发... 只是还是比較认真的做了三个月,老师非常认同我的工作态度和成果.. . 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题,分享 ...

  5. 使用Samba在Linux服务器上搭建共享文件服务

    最近我们的小团队需要在服务器上共分出一个共享文件夹用于大家存放公共的资源文档, 大家想啊,这肯定很简单呀,在Windows下面只要创建相关的windows account,共享某个文件夹,把读/写权限 ...

  6. 7 Java Performance Metrics to Watch After a Major Release--转

    原文地址:https://dzone.com/articles/7-java-performance-metrics-to-watch-after-a-major-1 The Java perform ...

  7. js课程 3-10 js中字符串函数数组函数和其它语言中对应函数的区别和联系是什么

    js课程 3-10  js中字符串函数数组函数和其它语言中对应函数的区别和联系是什么 一.总结 一句话总结:js中是对象点方法的形式,这些方法都是对象的方法,而在php.java中却不是这样. 1.j ...

  8. 将OpenCV捕获的摄像头加载到picture控件中

    CRect rect; CStatic* pStc; CDC* pDC; HDC hDC; pStc = (CStatic*)GetDlgItem(IDC_CAM);//IDC_CAM是Picture ...

  9. JVM调优基础 分类: B1_JAVA 2015-03-14 09:33 250人阅读 评论(0) 收藏

    一.JVM调优基本流程 1.划分应用程序的系统需求优先级 2.选择JVM部署模式:单JVM.多JVM 3.选择JVM运行模式 4.调优应用程序内存使用 5.调优应用程序延迟 6.调优应用程序吞吐量 二 ...

  10. 漂亮的Android加载中动画:AVLoadingIndicatorView

    AVLoadingIndicatorView 包含一组漂亮的Android加载中动画. IOS版本:here. 示例 Download Apk 用法 步骤1 Add dependencies in b ...