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,000。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过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

网上的题解基本上没有证明(或许有,但是我没看见,然后懒得找了)

两个最小生成树的权值相同的边作用相同(连通情况)

我们可以用反证法

假设有两个最小生成树的权值相同的边作用不同,那么把最小的作用不同的权值找出来

然后我们把他们的连通情况合并(去环),需要的边肯定会变多,而且一定可以做到,相当于我们用多出来的边代替了权值比它大的边,那这与前面说的这是最小生成树矛盾

例:假设权值为1的边在一棵最小生成树里造成连通情况是(1,2)(3,4),在另一棵最小生成树里造成的连通情况是(1,4)(2,3)

那我们可以合并它们用权值为1的边做到(1,2,3,4),来替换一条权值大于1的边,得到一颗权值更小的树

证毕.

所以我们记录每种权值的边所造成的连通情况记录下来,每个权值做一遍,乘起来就是答案(注意判断无解的情况)

  1 const
  2     maxn=105;
  3     maxm=1010;
  4     h=31011;
  5 var
  6     ans,n,m,l:longint;
  7     u,v,w:array[0..maxm]of longint;
  8     a:array[0..10,0..1024]of longint;
  9
 10 procedure swap(var x,y:longint);
 11 var
 12     t:longint;
 13 begin
 14     t:=x;x:=y;y:=t;
 15 end;
 16
 17 procedure sort(l,r:longint);
 18 var
 19     i,j,y:longint;
 20 begin
 21     i:=l;
 22     j:=r;
 23     y:=w[(l+r)>>1];
 24     repeat
 25       while w[i]<y do
 26         inc(i);
 27       while w[j]>y do
 28         dec(j);
 29       if i<=j then
 30       begin
 31         swap(u[i],u[j]);
 32         swap(v[i],v[j]);
 33         swap(w[i],w[j]);
 34         inc(i);
 35         dec(j);
 36       end;
 37     until i>j;
 38     if i<r then sort(i,r);
 39     if j>l then sort(l,j);
 40 end;
 41
 42 function bit(x:longint):longint;
 43 begin
 44     if x=0 then exit(0);
 45     exit(bit(x-(x and -x))+1);
 46 end;
 47
 48 procedure init;
 49 var
 50     i,k:longint;
 51 begin
 52     read(n,m);
 53     for i:=1 to m do
 54       read(u[i],v[i],w[i]);
 55     sort(1,m);
 56     for i:=0 to 1023 do
 57       begin
 58         k:=bit(i);
 59         inc(a[k,0]);
 60         a[k,a[k,0]]:=i;
 61       end;
 62 end;
 63
 64 var
 65     f,f2,vis:array[0..maxn]of longint;
 66     xu:array[0..maxm]of longint;
 67     time:longint;
 68
 69 function find(x:longint):longint;
 70 begin
 71     if vis[x]<>time then
 72     begin
 73       f[x]:=f2[x];
 74       vis[x]:=time;
 75     end;
 76     if f[x]=x then exit(x);
 77     f[x]:=find(f[x]);
 78     exit(f[x]);
 79 end;
 80
 81 function find2(x:longint):longint;
 82 begin
 83     if f2[x]=x then exit(x);
 84     f2[x]:=find2(f2[x]);
 85     exit(f2[x]);
 86 end;
 87
 88 function flag(x:longint):boolean;
 89 var
 90     i:longint;
 91 begin
 92     i:=0;
 93     while x>0 do
 94       begin
 95         inc(i);
 96         if x and 1=1 then
 97         begin
 98           if find(u[l+i])=find(v[l+i]) then exit(false);
 99           if (f[u[l+i]]<>f[v[l+i]])and(find2(u[l+i])=find2(v[l+i])) then exit(false);
100           f[f[u[l+i]]]:=f[v[l+i]];
101         end;
102         x:=x>>1;
103       end;
104     exit(true);
105 end;
106
107 procedure work;
108 var
109     i,j,s,last:longint;
110 begin
111     ans:=1;
112     for i:=1 to n do
113       f2[i]:=i;
114     for i:=1 to m do
115       begin
116         if w[i]=w[i-1] then xu[i]:=xu[i-1];
117         if find2(u[i])<>find2(v[i]) then
118         begin
119           inc(xu[i]);
120           f2[f2[u[i]]]:=f2[v[i]];
121         end;
122       end;
123     for i:=1 to n-1 do
124       if find2(i)<>find2(i+1) then ans:=0;
125     for i:=1 to n do
126       f2[i]:=i;
127     l:=0;
128     last:=0;
129     for i:=1 to m do
130       if w[i]<>w[i+1] then
131       begin
132         s:=0;
133         while last<l do
134           begin
135             inc(last);
136             f2[find2(u[last])]:=find2(v[last]);
137           end;
138         for j:=1 to a[xu[i],0] do
139           begin
140             if a[xu[i],j]>=1<<(i-l) then break;
141             inc(time);
142             if flag(a[xu[i],j]) then inc(s);
143           end;
144         l:=i;
145         ans:=ans*s mod h;
146       end;
147     write(ans);
148 end;
149
150 begin
151     init;
152     work;
153 end.

View Code

转载于:https://www.cnblogs.com/Randolph87/p/3624335.html

1016: [JSOI2008]最小生成树计数 - BZOJ相关推荐

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

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

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

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

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

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

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

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

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

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

  6. BZOJ1016:[JSOI2008]最小生成树计数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1016 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不 ...

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

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

  8. [JSOI2008]最小生成树计数

    OJ题号: BZOJ1016 题目大意: 给定一个无向带权图,求最小生成树的个数. 思路: 先跑一遍最小生成树,统计相同权值的边出现的个数. 易证不同的最小生成树,它们不同的那一部分边的权值实际上是相 ...

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

    题意:给定一张n<=100,m<=1000的无向图,另外同样权值的边不超过10条,求最小生成树的数目. 思路:首先我们将不同的权值从小到大分开考虑. 我们证明下面定理:一个无向图全部的最小 ...

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

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

最新文章

  1. LaText中插入带上下限的求和符号
  2. js选择日期即时把两个日期相差天数显示出来?
  3. (Metro学习三)图片uri保存到本地图片库
  4. php移动代码,移动专区周级收录如何提交 复制这段php代码即可
  5. 分享网页设计当中使用进度条打造精美界面最佳例子
  6. android slidingdrawer 方向,如何使Android SlidingDrawer从左侧滑出?
  7. python中number函数_Python 数字(Number)
  8. linux中如何运行html文件路径问题,Linux中如何查询运行文件的全路径的方法
  9. 三十六、【减小apk包的体积】
  10. 【MySQL】MySQL常见的读写分离方法
  11. nagios监控安装及设置案例
  12. 贴一个数据结构老师布置的作业(各种排序) c 语言实现
  13. 2017年BackBox5和Ubuntu16.04.1国内更新源
  14. 重设OS X (macOS)系统帐户密码的几种方法
  15. 增长黑客手册:如何用数据驱动爆发式增长_思维导图
  16. mysql 脱裤_mysql 脱裤(脱库)通用脚本 | 学步园
  17. 新鲜出炉2010笑话集锦,我竟然一个都没听过
  18. 要么励志故事:要么孤独,要么庸俗
  19. Matlab的plot函数画线显示空白问题解决
  20. 中英文说明书丨艾美捷双链RNA定量试剂盒

热门文章

  1. 如何通俗易懂地让女朋友明白什么是语言模型?
  2. 融入常识知识的生成式对话摘要
  3. 她是北大“一个人的毕业照”主人公,2010 级古生物专业独苗,十年后转行搞起了 NLP...
  4. 【每日算法Day 73】学妹大半夜私聊我有空吗,然后竟然做出这种事!
  5. nlp基础—11.条件随机场模型(CRF)模型补充
  6. 灵活地横向扩展:从文件系统到分布式文件系统
  7. 数据中台公开课丨可以复用的中台架构建设经验与实践
  8. 神奇的G1——Java全新垃圾回收机制
  9. 5.7 tensorflow2实现主成分分析(PCA) ——python实战(上篇)
  10. PyTorch:损失函数loss function