1016: [JSOI2008]最小生成树计数 - BZOJ
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的边,得到一颗权值更小的树
证毕.
所以我们记录每种权值的边所造成的连通情况记录下来,每个权值做一遍,乘起来就是答案(注意判断无解的情况)
const
maxn=;
maxm=;
h=;
var
ans,n,m,l:longint;
u,v,w:array[..maxm]of longint;
a:array[..,..]of longint; procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var
i,j,y:longint;
begin
i:=l;
j:=r;
y:=w[(l+r)>>];
repeat
while w[i]<y do
inc(i);
while w[j]>y do
dec(j);
if i<=j then
begin
swap(u[i],u[j]);
swap(v[i],v[j]);
swap(w[i],w[j]);
inc(i);
dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end; function bit(x:longint):longint;
begin
if x= then exit();
exit(bit(x-(x and -x))+);
end; procedure init;
var
i,k:longint;
begin
read(n,m);
for i:= to m do
read(u[i],v[i],w[i]);
sort(,m);
for i:= to do
begin
k:=bit(i);
inc(a[k,]);
a[k,a[k,]]:=i;
end;
end; var
f,f2,vis:array[..maxn]of longint;
xu:array[..maxm]of longint;
time:longint; function find(x:longint):longint;
begin
if vis[x]<>time then
begin
f[x]:=f2[x];
vis[x]:=time;
end;
if f[x]=x then exit(x);
f[x]:=find(f[x]);
exit(f[x]);
end; function find2(x:longint):longint;
begin
if f2[x]=x then exit(x);
f2[x]:=find2(f2[x]);
exit(f2[x]);
end; function flag(x:longint):boolean;
var
i:longint;
begin
i:=;
while x> do
begin
inc(i);
if x and = then
begin
if find(u[l+i])=find(v[l+i]) then exit(false);
if (f[u[l+i]]<>f[v[l+i]])and(find2(u[l+i])=find2(v[l+i])) then exit(false);
f[f[u[l+i]]]:=f[v[l+i]];
end;
x:=x>>;
end;
exit(true);
end; procedure work;
var
i,j,s,last:longint;
begin
ans:=;
for i:= to n do
f2[i]:=i;
for i:= to m do
begin
if w[i]=w[i-] then xu[i]:=xu[i-];
if find2(u[i])<>find2(v[i]) then
begin
inc(xu[i]);
f2[f2[u[i]]]:=f2[v[i]];
end;
end;
for i:= to n- do
if find2(i)<>find2(i+) then ans:=;
for i:= to n do
f2[i]:=i;
l:=;
last:=;
for i:= to m do
if w[i]<>w[i+] then
begin
s:=;
while last<l do
begin
inc(last);
f2[find2(u[last])]:=find2(v[last]);
end;
for j:= to a[xu[i],] do
begin
if a[xu[i],j]>=<<(i-l) then break;
inc(time);
if flag(a[xu[i],j]) then inc(s);
end;
l:=i;
ans:=ans*s mod h;
end;
write(ans);
end; begin
init;
work;
end.
1016: [JSOI2008]最小生成树计数 - BZOJ的更多相关文章
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
- [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】
题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数(kruskal+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1016 想也想不到QAQ 首先想不到的是:题目有说,具有相同权值的边不会超过10条. 其次:老是去想组 ...
- BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)
题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...
- bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...
随机推荐
- PS基础学习 2---图层蒙版
1,蒙版,字面意思上的理解就是:把底层图片上面加上一层图层蒙着,通过画笔工具控制底层图片和上面一层图层的显示效果.常用于图层的无缝隙合成. 我们可以先看一下下面的这个小例子,这个就是蒙版的一个小应用: ...
- firebug调试js时提示调试器未激活处理办法
firebug是web开发中最常用的分析调试软件,不过我今天使用在调试百度在线编辑器UEditor时一直提示调试器未激活. 从使用经验来看不应该啊,我都下了断点了为什么会提示调试器未激活呢!多次载入网 ...
- Could not delete folder on Win7
I had the same problem on Win 7 and this worked for me in command prompt. Solution 1: RD/S pathname ...
- 20141015--for语句2
for语句,打印等腰三角形: 第一种方法:(使用for语句嵌套) 第二种方法:(定义string型变量) 以下是其他形状的等腰三角形: (穿插使用了for语句嵌套,定义string型)
- 委托和事件[delegate and event]_C#
委托和事件: 1. 委托:一个能够表示方法的数据类型:它将方法作为对象封装起来,允许在运行时间接地绑定一个方法调用. 2. 声明委托数据类型: public delegate bool Greate ...
- Smarty模板引擎技术
Smarty模板引擎技术 什么是模板引擎? 什么是Smarty模板引擎? 为何选择Smarty模板引擎? 如何使用Smarty模板引擎? 一.历史背景 场景一:回顾之前编写PHP项目的方式 //链接数 ...
- bzoj3389:[Usaco2004 Dec]Cleaning Shifts安排值班
思路:可以贪心,也可以最短路. 贪心写法:因为在保证合法的前提下,我们选择的区间一定要右端点尽量靠后才行,于是我们每次就选择一个合法的并且右端点最靠后的区间就好了(如果没有合法的输出-1即可).时间复 ...
- OpenJudge 2721 忽略大小写比较字符串大小
1.Link: http://bailian.openjudge.cn/practice/2721/ 2.Content: 总时间限制: 1000ms 内存限制: 65536kB 描述 一般我们用st ...
- 给LinkLabel文本绘制颜色
我在form中有一个linkLabel,显示文字是“中秋快乐”.现在我希望其中的“中秋”两个字用红色字体显示,“快乐”用黑色字体.请问如何在一个linkLabel中实现上述效果? 答案: privat ...
- DTCMS自定义标签,获取所有栏目以及获得二级子栏目导航
取得二级栏目 DTcms.Web.UI\Label\category.cs中 get_category_child_list 返回当前所有子栏目 DTcms.Web.UI\Label\category ...