题目描述

现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。

输入输出格式

输入格式:
第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整数编号。

接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,000。

数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。

输出格式:
输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。

输入输出样例

输入样例#1:
4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
输出样例#1:
8
说明

说明 1<=n<=100; 1<=m<=1000;1≤ci≤1091≤c_i≤10^91≤ci​≤109。

分析:
一个图不同的最小生成树有两个性质。
第一是所有最小生成树中相同权值的边使用了相同多次。我们考虑我们已经建好了一棵最小生成树,对于一条不在这棵树上的边(u,v)(u,v)(u,v),保证在树上uuu到vvv的路径上的权值都小于等于这条边的权值,而且只有替换相同权值的边,新树才会是最小生成树。
第二是同一种权值的边连完后,连通块完全一样。也可以理解为相同权值的边无论怎样先后顺序如何,连接后的连通块完全一样。这个是很显然的。
假如我们假如了权值小于www的边,形成若干连通块。此时加入边权为www的边,将会连接一些连通块,把这些连通块看做点,连接相当于形成一棵树,使用矩阵树就可以。还有一种特殊情况,就是同一种边权的边连接形成的不是一个连通图。举个例子,比如说第一条边连接了111和222,第二条边连接333和444,此时如果直接建图做矩阵树det就是000。那么我们可以强行把他建成连通图,把每个连通块连成一个链,因为链上的边一定会被选,所以相当于每个连通块的树的个数的乘积。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define LL long longconst int maxn=107;
const int maxe=1007;
const LL mod=31011;using namespace std;int n,m,cnt;
LL a[maxn][maxn];
int b[maxn],p[maxn],f[maxn];struct edge{int x,y,w;
}g[maxe];bool cmp(edge x,edge y)
{return x.w<y.w;
}int find(int x,int *p)
{int y=x,root;while (p[x]) x=p[x];root=x;x=y;while (p[x]){y=p[x];p[x]=root;x=y;}return root;
} void uni(int x,int y,int *p)
{int u=find(x,p);int v=find(y,p);if (u==v) return;p[u]=v;
}LL det()
{int n=cnt-1;LL ans=1;for (int i=1;i<=n;i++){for (int j=i+1;j<=n;j++){while (a[j][i]){LL rate=a[i][i]/a[j][i];for (int k=i;k<=n;k++){a[i][k]=(a[i][k]-rate*a[j][k]%mod+mod)%mod;swap(a[i][k],a[j][k]);}ans=mod-ans;}}ans=(ans*a[i][i])%mod;}return ans;
}int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=m;i++) scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].w);sort(g+1,g+m+1,cmp);LL ans=1,num=0;  for (int i=1,last;i<=m;i=last+1){last=i;memset(b,0,sizeof(b));memset(a,0,sizeof(a));memset(f,0,sizeof(f));cnt=0;while (g[i].w==g[last].w){int x=g[last].x;int y=g[last].y;if (find(x,p)!=find(y,p)){int u=find(x,p),v=find(y,p);if (b[u]==0) b[u]=++cnt;if (b[v]==0) b[v]=++cnt;a[b[u]][b[v]]=(a[b[u]][b[v]]-1+mod)%mod;a[b[v]][b[u]]=(a[b[v]][b[u]]-1+mod)%mod;a[b[u]][b[u]]++;a[b[v]][b[v]]++;uni(b[u],b[v],f);}last++;}last--;for (int j=2;j<=cnt;j++){if (find(j,f)!=find(j-1,f)){uni(j-1,j,f);a[j-1][j]=(a[j-1][j]-1+mod)%mod;a[j][j-1]=(a[j][j-1]-1+mod)%mod;a[j-1][j-1]++;a[j][j]++;}}ans=(ans*det())%mod;for (int j=i;j<=last;j++){if (find(g[j].x,p)!=find(g[j].y,p)){num++;uni(g[j].x,g[j].y,p);}}}if (num<n-1) printf("0");else printf("%lld",ans);
}

洛谷 P4208 [JSOI2008]最小生成树计数 矩阵树定理相关推荐

  1. BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】

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

  2. 洛谷4455 [CQOI2018]社交网络 (有向图矩阵树定理)(学习笔记)

    sro_ptx_orz qwq算是一个套路的记录 对于一个有向图来说 如果你要求一个外向生成树的话,那么如果存在一个\(u\rightarrow v\)的边 那么\(a[u][v]--,a[v][v] ...

  3. 最小生成树、矩阵树定理、Prufer序列总结

    Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...

  4. P4208 [JSOI2008]最小生成树计数

    传送门 首先最小生成树有这么两个性质 1.不同的最小生成树中,每种权值的边出现的个数是确定的2.不同的生成树中,某一种权值的边连接完成后,形成的联通块状态是一样的 打个比方,以下图为例(图是网上的) ...

  5. 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理

    蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...

  6. [XSY]Tree Ext(矩阵树定理,拉格朗日插值,最小生成树,二分)

    Tree Ext 这道题相当于把3道题合了起来. 要求修复的边中恰好有 k 条白边: 五颜六色的幻想乡(附拉格朗日插值法求多项式系数 ) + bzoj2654 tree(WQS二分 新科技get) 是 ...

  7. bzoj1016 [JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 6032  Solved: 2452 [Submit][ ...

  8. 洛谷P4037 [JSOI2008]魔兽地图 题解

    洛谷P4037 [JSOI2008]魔兽地图 题解 题目链接:P4037 [JSOI2008]魔兽地图 题意: DotR (Defense of the Robots) Allstars是一个风靡全球 ...

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

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

最新文章

  1. R使用深度学习LSTM构建时间序列预测模型
  2. keras merge
  3. 神策数据胡士文:数据智能驱动业务实践
  4. 数据大屏产品介绍PPT_有这些图表美化工具,十分钟配出炫酷的数据可视化大屏...
  5. 环状进度条progress bar circle
  6. java项目中Classpath路径到底指的是哪里?
  7. Python中的运算符是什么?本文详解!
  8. 传聊天宝团队解散 罗永浩已退出股东行列
  9. java redis的应用_Redis-Java 交互的应用
  10. Idea 集成Lombok插件
  11. js模仿块级作用域(js没有块级作用域私有作用域)
  12. c语言:【顺序表】静态顺序表的删除指定位置元素Erase、删除指定元素Remove
  13. Oracle单实例数据库迁移到Oracle RAC 环境之(3)--主备库Switchover
  14. Hadoop专业解决方案-第5章 开发可靠的MapReduce应用
  15. 软件工作量评估方法(一)
  16. 黑苹果(Hackintosh)简单步骤教程
  17. 【游戏客户端】实现游戏中的小地图
  18. 完善:HTML5表单新特征简介与举例——张鑫旭
  19. 17 Flask mega-tutorial 第17章 在Linux上部署(腾讯云 Ubuntu)【极其详细的部署过程】
  20. 如何检索、写作和顺利发表一篇SCI论文?

热门文章

  1. 20万、50万、100万的算法工程师,有什么区别?
  2. pe联想服务器装系统教程视频,演示联想电脑u盘重装系统xp教程
  3. 腾讯、阿里也开始裁员了,失业来得太突然…
  4. chm打开秒退_Mac_Mac电脑程序无响应怎么办?Mac程序无响应解决方法,虽然Mac电脑一向以运行稳定、 - phpStudy...
  5. 武汉新时标文化传媒有限公司短视频创作者实现突围?
  6. USB开设备开发学习之三:USB中的端点详细了解
  7. wps指定路径不存在怎么办_wps指定路径不存在怎么办_十万人都不知道键盘上 F1~F12 的作用,你肯定想不到......
  8. 巴东县黄土坡滑坡GNSS自动化位移监测解决方案
  9. 联想Y7000如何切换性能模式
  10. 使用outlook 2007配置microsoft exchange邮箱方法步骤