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

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4863  Solved: 1973
[Submit][Status][Discuss]

Description

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

Input

  第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整
数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,0
00。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。

Output

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

Sample Input

4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1

Sample Output

8
 
 
 
【题解】

就是不同的最小生成树方案,每种权值的边的数量是确定的,每种权值的边的作用是确定的

排序以后先做一遍最小生成树,得出每种权值的边使用的数量x

然后对于每一种权值的边搜索,得出每一种权值的边选择方案

然后乘法原理

转自——hzwer.com

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<cmath>
  7. #include<ctime>
  8. using namespace std;
  9. #define mod 31011
  10. int n,m,len,sum,tot,ans=,f[];
  11. struct node{int x,y,v;}e[];
  12. struct sha{int l,r,v;}a[];
  13. bool cmp(node a,node b) {return a.v<b.v;}
  14. int find(int x) {return f[x]==x?x:find(f[x]);}
  15. namespace INIT
  16. {
  17. char buf[<<],*fs,*ft;
  18. inline char getc() {return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;}
  19. inline int read()
  20. {
  21. int x=,f=; char ch=getc();
  22. while(!isdigit(ch)) {if(ch=='-') f=-; ch=getc();}
  23. while(isdigit(ch)) {x=x*+ch-''; ch=getc();}
  24. return x*f;
  25. }
  26. }using namespace INIT;
  27. void dfs(int x,int now,int k)
  28. {
  29. if(now==a[x].r+)
  30. {
  31. if(k==a[x].v) sum++;
  32. return;
  33. }
  34. int p=find(e[now].x),q=find(e[now].y);
  35. if(p!=q)
  36. {
  37. f[p]=q;
  38. dfs(x,now+,k+);
  39. f[p]=p; f[q]=q;
  40. }
  41. dfs(x,now+,k);
  42. }
  43. int main()
  44. {
  45. //freopen("cin.in","r",stdin);
  46. //freopen("cout.out","w",stdout);
  47. n=read(); m=read();
  48. for(int i=;i<=n;i++) f[i]=i;
  49. for(int i=;i<=m;i++) e[i].x=read(),e[i].y=read(),e[i].v=read();
  50. sort(e+,e+m+,cmp);
  51. for(int i=;i<=m;i++)
  52. {
  53. if(e[i].v!=e[i-].v) {a[++len].l=i;a[len-].r=i-;}
  54. int p=find(e[i].x),q=find(e[i].y);
  55. if(p!=q) {f[p]=q; a[len].v++; tot++;}
  56. }
  57. a[len].r=m;
  58. if(tot!=n-) {printf("0\n"); return ;}
  59. for(int i=;i<=n;i++) f[i]=i;
  60. for(int i=;i<=len;i++)
  61. {
  62. sum=;
  63. dfs(i,a[i].l,);
  64. ans=(ans*sum)%mod;
  65. for(int j=a[i].l;j<=a[i].r;j++)
  66. {
  67. int p=find(e[j].x),q=find(e[j].y);
  68. if(p!=q) f[p]=q;
  69. }
  70. }
  71. printf("%d\n",ans);
  72. return ;
  73. }

【bzoj1016】[JSOI2008]最小生成树计数的更多相关文章

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

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

  2. bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)

    1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等  就是说如果一种方案中权值为1的边有n条 ...

  3. BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)

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

  4. [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)

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

  5. 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数

    题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...

  6. [BZOJ1016][JSOI2008]最小生成树计数(结论题)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E ...

  7. [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)

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

  8. 【最小生成树】BZOJ1016: [JSOI2008]最小生成树计数

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

  9. 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)

    传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...

  10. [BZOJ1016][JSOI2008]最小生成树计数 最小生成树 搜索

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如 ...

随机推荐

  1. asp.net identity的学习记录

    # identity数据库 ## 创建空数据库 交给ef管理 ### 添加asp.net identity包 ``` Install-Package Microsoft.AspNet.Identity ...

  2. php session在高并发时可能存在的问题。

    如果同一个客户端并发发送多个请求,而每个请求都使用了Session,那么PHP Session锁的存在会导致服务器串行响应这些请求,而不是并行.这是因为在默认情况下,PHP使用文件存储Session数 ...

  3. Django初体验——搭建简易blog

    前几天在网上看到了篇采用Django搭建简易博客的视频,好奇心驱使也就点进去学了下,毕竟自己对于Django是无比敬畏的,并不是很了解,来次初体验. 本文的操作环境:ubuntu.python2.7. ...

  4. bulkcopy实现批量插入与更新

    public static void UpdateData<T>(List<T> list, string TabelName) { DataTable dt = new Da ...

  5. HihoCoder1620: 股票价格3 (单调队列 or DP)

    股票价格3 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在关注股票,为了计算股票可能的盈利,他获取了一只股票最近N天的价格A1~AN. 小Hi想知道,对于第 ...

  6. bzoj 2770 YY的Treap

    Written with StackEdit. Description 志向远大的\(YY\)小朋友在学完快速排序之后决定学习平衡树,左思右想再加上\(SY\)的教唆,\(YY\)决定学习\(Trea ...

  7. Linux下更改oracle客户端字符集和服务端字符集

    from:http://blog.csdn.net/chid/article/details/6166506 Linux 下更改 oracle 客户端字符集和服务端字符集 1.Linux 下更改 or ...

  8. 记录几个基础的SQL开发题

    1. 表A有5行数据,表B有7行数据,问Inner Join最多返回几行数据,Left Join最多返回几行数据,分别在什么情况下? Inner Join 是返回关联表的Cartesian produ ...

  9. python中reload(module)的用法,以及错误提示

    1.Python2中可以和Python3中关于reload()用法的区别. Python2 中可以直接使用reload(module)重载模块.   Pyhton3中需要使用如下两种方式: 方式(1) ...

  10. ORA-28595: Extproc 代理: DLL 路径无效解决办法

    报错信息: ORA-28595: Extproc 代理: DLL 路径无效 ORA-06512: 在 "SDE.ST_GEOMETRY_SHAPELIB_PKG", line 70 ...