@[最小生成樹, 排列組合]

Discription

现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的

最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生

成树可能很多,所以你只需要输出方案数对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

Solution

具體做法:

  1. 跑一遍最小生成樹, 統計最小生成樹中每一種權值的邊的出現次數\(sum\), 順便將圖中 所有 邊進行離散化;
  2. 查找在每一種權值的邊中選出\(sum\)條邊, 使得選出的邊滿足每一條邊所連接的都是兩個不同的并查集的組合數量;
  3. 在上一步的答案乘上這個數量(乘法原理), 並且將這種權值的所有邊所連接的并查集都連接起來;

嗯, 結束.

具體爲什麽這種做法能成立, 我也不知道QAQ

代碼比較傻, 隨便找了一個貼上

#include <bits/stdc++.h>
using namespace std;
struct edge
{
int u, v, w, x;
inline bool operator< (const edge &rhs) const
{
return x < rhs.x;
}
}e[1005];
struct count
{
int l, r, use;
}g[1005];
int n, m, fa[105], siz[105]; int getfa(int x)
{
return fa[x] == x ? x : getfa(fa[x]);
} void link(int u, int v)
{
if(siz[u] > siz[v]) fa[v] = u, siz[u] += siz[v];
else fa[u] = v, siz[v] += siz[u];
} bool Kruskal()
{
int cnt = 0, u, v;
for(int i = 1; i <= m; ++i)
{
u = getfa(e[i].u), v = getfa(e[i].v);
if(u != v)
{
link(u, v);
++g[e[i].w].use;
if(++cnt == n - 1) return true;
}
}
return false;
} int DFS(int w, int i, int k)
{
if(k == g[w].use) return 1;
if(i > g[w].r) return 0;
int ans = 0, u = getfa(e[i].u), v = getfa(e[i].v);
if(u != v)
{
link(u, v);
ans = DFS(w, i + 1, k + 1);
fa[u] = u, fa[v] = v;
}
return ans + DFS(w, i + 1, k);
} int main()
{
int u, v, w, ans;
cin >> n >> m;
for(int i = 1; i <= n; ++i)
fa[i] = i, siz[i] = 1;
for(int i = 1; i <= m; ++i)
{
cin >> u >> v >> w;
e[i] = (edge){u, v, 0, w};
}
sort(e + 1, e + m + 1);
w = 0;
for(int i = 1; i <= m; ++i)
if(e[i].x == e[i - 1].x) e[i].w = w;
else
{
g[w].r = i - 1;
e[i].w = ++w;
g[w].l = i;
}
g[w].r = m;
ans = Kruskal();
for(int i = 1; i <= n; ++i)
fa[i] = i, siz[i] = 1;
for(int i = 1; i <= w; ++i)
{
ans = ans * DFS(i, g[i].l, 0) % 31011;
for(int j = g[i].l; j <= g[i].r; ++j)
{
u = getfa(e[j].u), v = getfa(e[j].v);
if(u != v) link(u, v);
}
}
cout << ans << endl;
return 0;
}

BZOJ1016最小生成树计数 最小生成树 + 排列组合的更多相关文章

  1. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas

    [题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...

  2. 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

    [题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...

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

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

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

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

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

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

  6. $bzoj1016-JSOI2008$ 最小生成树计数 最小生成树 $dfs/matrix-tree$定理

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

  7. 【BZOJ4517】排列计数(排列组合)

    题意:1-n的一个序列,其中有m个a[i]=i,求方案数 n,m<=1000000 题意:显然ANS=c(n,m)*d[n-m] d[i]为错排方案数=d[i-1]*n+(-1)^n ; ..] ...

  8. 【bzoj1016】 JSOI2008—最小生成树计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...

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

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

随机推荐

  1. CSS - position属性小结

    Relative: 属于文档流,针对自身进行偏移: Absolute: 脱离文档流,针对最近的定位元素进行偏移,如果没有,则针对根元素,即body标签尽心偏移: Fixed: 和absolute基本一 ...

  2. SQL 牛刀小试 1 —— 查询操作

    #创建数据库create database ST CHARACTER set utf8;#创建用户create user ST identified by '19980510';#授权用户操作该数据库 ...

  3. Ubuntu sudo 出现 is not in the sudoers file解决方案

    前言: 自己想额外创建一个Linux账户,但是发现新创建的用户(lgq)并不能使用sudo指令. 但是在安装系统时创建的用户(abc)是可以正常使用的. 原因是新创建的用户并没有被赋予使用sudo指令 ...

  4. Linux系统状态检测

    基于Red Hat Enterprise Linux 7.5 1.ifconfig ifconfig用于获取和配置网络接口的网络参数,格式为“ifconfig [网络设备] [参数]” 参数: add ...

  5. getComputedStyle与currentStyle获取元素当前的css样式

    CSS的样式分为三类: 内嵌样式:是写在标签里面的,内嵌样式只对所在的标签有效内部样式:是写在HTML里面的,内部样式只对所在的网页有效外部样式表:如果很多网页需要用到同样的样式,将样式写在一个以.c ...

  6. day18-python之迭代器和生成器

    1.文件处理模式b模式 #!/usr/bin/env python # -*- coding:utf-8 -*- # f=open('test.py','rb',encoding='utf-8') # ...

  7. Oracle联合主键

    转https://www.cnblogs.com/king-xg/p/6721272.html alter table tablename add constraint unionkeyname pr ...

  8. HashMap图解

    HashMap的数据结构和put.get.resize等操作的图解,看图轻松掌握HashMap (目前还不包括红黑树相关的部分) HashMap数据结构如下图 HashMap之put操作如下图 Has ...

  9. hadoop学习爬坑记录

    1. Q: hdfs管理界面50070端口设置后,无法访问情况. A: 1)停止当前所有服务./stop-all.sh 2)在hdfs-site.xml中,更改开放端口的绑定IP: <prope ...

  10. hdu2081

    #include <stdio.h> #include <malloc.h> int main(){ ]; char *p; int t; p=(); scanf(" ...