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的更多相关文章

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

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

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

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

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

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

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

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

  5. 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集

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

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

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

  7. 【BZOJ】1016: [JSOI2008]最小生成树计数(kruskal+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016 想也想不到QAQ 首先想不到的是:题目有说,具有相同权值的边不会超过10条. 其次:老是去想组 ...

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

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

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

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

随机推荐

  1. sort排序中的坑

    问题的产生原因: 在一篇阿里面试题的跟帖中,很多人应用sort()方法对数组进行排序.看似合情合理的代码,运行结果却频频出错.为什么呢?因为很多人都忽略掉了一点,那就是sort()排序默认情况下是按A ...

  2. MongoDB - Introduction to MongoDB, BSON Types

    BSON is a binary serialization format used to store documents and make remote procedure calls in Mon ...

  3. MyEclipse中配置SWT/JFace/SWT-Designer 艰辛路程

    我最近受一个老师所托,写一个小系统,为了更加熟练使用Java,我决定用Java写一个PC软件. 我是一个比较追求完美的孩子,所以虽然老师对界面没啥要求,但是为了加快速度和界面美观,果断选择SWT/JF ...

  4. windows server 2008下装SQL 2008R2x64

    1. 在windows server 2008下装SQL 2008出现 This SQL Server Setup media is not supported on a X64 system 使用虚 ...

  5. 如何让Asp.net webAPI返回JSON格式数据

    ASP.NET Web API 是新一代的 HTTP 網路服務開發框架,除了可以透過 Visual Studio 2012 快速開發外 (內建於 ASP.NET MVC 4 的 Web API 專案範 ...

  6. HTML+CSS学习笔记(4) - 认识标签(3)

    HTML+CSS学习笔记(4) - 认识标签(3) 1.使用<a>标签,链接到另一个页面 使用<a>标签可实现超链接,它在网页制作中可以说是无处不在,只要有链接的地方,就会有这 ...

  7. ios开发----视图的生命周期

    熟悉web开发的朋友可能对页面page的生命周期有一定的了解和认识,正如web开发中的页面生命周期一样,移动客户端开发也有它自己的生命周期.下文将说明ios开发中视图的生命周期既运行顺序. 在ios视 ...

  8. iOS的沙箱目录和文件操作

    一.沙箱 iOS的每一个应用程序都有自己的目录来存放数据,这个目录称为沙箱目录.沙箱目录是一种数据安全策略,它设计的原理是只能允许自己的应用访问目录,而不允许其他的应用访问,这样可以保证数据的安全,应 ...

  9. C#中Excel的导入和导出的几种基本方式

    在上一篇(http://www.cnblogs.com/fengchengjushi/p/3369386.html)介绍过,Excel也是数据持久化的一种实现方式.在C#中.我们常常会与Excel文件 ...

  10. JAVA_SE复习(basic)

    一.数据类型 1.基本数据类型 Ps:有效标识符:_.字母.$开头  之后可有数字 整型:byte 1 short 2 int 4 long 8  (字节) 取值范围:其范围是从负2 的该数据类型位数 ...