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

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. shell脚本,如何写进度条。

    [root@localhost ~]# cat jindutiao.sh #!/bin/bash #进度条 n=$((/)) N=$((/)) ` do sleep 0.01 [ $(($i%$n)) ...

  2. 继上一篇随笔,优化3张以上图片轮播React组件

    import React from 'react'; import PropTypes from 'prop-types'; import {getSwipeWay} from '../utils/s ...

  3. POJ-3050-Hoscotch

    这是一道简单的深搜题目,题意说的是给一个5*5的棋盘,里面填满数字,然后跳到一个格子上,这是第一步,接着向上下左右四个方向任意一个方向走一步,一共走6步,问我们走过的数字组成的一个6位数有多少种不同的 ...

  4. 5.电影搜索之 自动填充,也叫autocomplete、搜索建议!

    什么叫自动填充,用过百度的应该都知道!当你输入关键词之后,会有一个下拉的候选列表,都是与你输入的内容相关的,这个就是自动填充的搜索建议.一般的搜索引擎或者站内搜索都会有这个功能. 今天分享下这个功能的 ...

  5. I2C驱动框架(二)

    参考:I2C子系统之I2C bus初始化——I2C_init() 在linux内核启动的时候最先执行的和I2C子系统相关的函数应该是driver/i2c/i2c-core.c文件中的i2c_init( ...

  6. Codeforces C. Sonya and Problem Wihtout a Legend(DP)

    Description Sonya was unable to think of a story for this problem, so here comes the formal descript ...

  7. ios开发中关闭textview控件的虚拟键盘

    在ios开发中,textfield控件在点击的时候出现虚拟键盘,关掉虚拟键盘可以通过虚拟键盘中的done button和点击view中的任意地方来关闭虚拟键盘. 1.第一种方法是textfield控件 ...

  8. centos 装 jdk

    1.源码包准备: 首先到官网下载jdk,http://www.oracle.com/technetwork/java/javase/downloads/jdk7- downloads-1880260. ...

  9. idea xml 一键生成 javabean

    操作步骤 1.复制的xml文件到工程的一个文件下 2.选中文件tools -> XML ACTIONS -> Generate schema from instance Document ...

  10. asp.net下js调用session

    大致方法为:js调用webservise,然后通过webservise将session值返回给js完成调用 其实最主要的一点就是在webmethod中允许session:[WebMethod(Enab ...