题目链接:

id=1016">点击打开链接

裸题

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if (x>9) pt(x / 10);
putchar(x % 10 + '0');
}
using namespace std;
typedef long long ll;
const int N = 105; //点的个数
const int M = 1005; //边的个数
//点标从1-n
struct node {
int set[N];
void init(int n) {
for (int i = 0; i <= n; i++) set[i] = i;
}
int find(int x) {
return x == set[x] ? x : set[x] = find(set[x]);
}
int Union(int x, int y) {
int xx = find(x);
int yy = find(y);
if (xx == yy) return -1;
set[xx] = yy;
return 1;
}
}a, b, c; struct Node {
int u, v, dis;
}edge[M];
int edgenum;
void add(int u, int v, int d){
Node E = { u, v, d };
edge[++edgenum] = E;
} bool visit[N];
vector<int> g[N];
ll p[N][N], deg[N][N];
int cmp(Node a, Node b) {
return a.dis < b.dis;
}
ll DET(ll a[][N], int n, ll MOD)
{
int i, j, k;
ll temp = 1, t;
for (i = 0; i < n; i++) for (j = 0; j < n; j++) a[i][j] %= MOD;
for (i = 1; i < n; i++)
{
for (j = i + 1; j < n; j++) while (a[j][i])
{
t = a[i][i] / a[j][i];
for (k = i; k < n; k++)
{
a[i][k] -= a[j][k] * t;
a[i][k] %= MOD;
}
for (k = i; k < n; k++)
swap(a[i][k], a[j][k]); temp = -temp;
}
temp = temp*a[i][i] % MOD;
}
return (temp + MOD) % MOD;
} ll cal_MST_count(int n, ll MOD) {
sort(edge + 1, edge + edgenum + 1, cmp);
int pre = edge[1].dis;
ll ans = 1;
a.init(n);
b.init(n);
memset(visit, 0, sizeof(visit));
memset(deg, 0, sizeof(deg));
for (int i = 0; i <= n; i++) g[i].clear();
for (int t = 1; t <= edgenum + 1; t++)
{
if (edge[t].dis != pre || t == edgenum + 1)
{
for (int i = 1, k; i <= n; i++) if (visit[i])
{
k = b.find(i);
g[k].push_back(i);
visit[i] = 0;
}
for (int i = 1; i <= n; i++)
if (g[i].size())
{
memset(p, 0, sizeof(p));
for (int j = 0; j < g[i].size(); j++)
for (int k = j + 1, x, y; k < g[i].size(); k++)
{
x = g[i][j];
y = g[i][k];
p[j][k] = p[k][j] = -deg[x][y];
p[j][j] += deg[x][y];
p[k][k] += deg[x][y];
}
ans = ans*DET(p, g[i].size(), MOD) % MOD;
for (int j = 0; j < g[i].size(); j++) a.set[g[i][j]] = i;
}
memset(deg, 0, sizeof(deg));
for (int i = 1; i <= n; i++)
{
b.set[i] = a.find(i);
g[i].clear();
}
if (t == edgenum + 1) break;
pre = edge[t].dis;
}
int x = a.find(edge[t].u);
int y = a.find(edge[t].v);
if (x == y) continue;
visit[x] = visit[y] = 1;
b.Union(x, y);
deg[x][y]++;
deg[y][x]++;
}
if (!edgenum) return 0;
for (int i = 2; i <= n; i++)
if (b.find(i) != b.find(1))
return 0;
return ans;
}
void init(){ edgenum = 0; }
int n, m, u, v, d;
ll mod;
int main(){
while (cin >> n >> m){
init();
while (m--){
rd(u); rd(v); rd(d);
add(u, v, d);
}
pt(cal_MST_count(n, 31011LL)); putchar('\n');
}
return 0;
}

BZOJ1016 &amp;&amp; JSOI2008] 最小生成树计数的更多相关文章

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

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

  2. bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)

    1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等  就是说如果一种方案中权值为1的边有n条 ...

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

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

  4. [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)

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

  5. 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数

    题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...

  6. [BZOJ1016][JSOI2008]最小生成树计数(结论题)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E ...

  7. [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)

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

  8. 【最小生成树】BZOJ1016: [JSOI2008]最小生成树计数

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

  9. 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)

    传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...

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

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

随机推荐

  1. python之GUI自定义界面设计 2014-4-10

    #自定义界面设计mybutton = Button(parent, **configuration options)也可以这么写mybutton.configure(**options)颜色可以用rg ...

  2. AutoItLibrary之键盘操作(send)

    最近有人问到我键盘操作用什么库?用到库里面的哪个方法?我在这里总结一下,第一次写,有片面的地方还请指出,一块进步.1.首先,用到的库是AutoItLibrary,用到的方法是send:按F5可用看到 ...

  3. Android弹幕编程设计实现的解决方案(一)

     Android弹幕编程设计实现的解决方案(一) 在现在的一些视频类网站.视频类直播网站,比如A站和B站,当视频在播放的时候,会在屏幕上出现一些滚动的字幕,这些字幕是UGC,通常是用户的评论,称之 ...

  4. 尼姆博弈扩展形式(一): 限定每次取物的上限。NYOJ-135,难度5~~~

    取石子(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 http://acm.nyist.net/JudgeOnline/problem.php?pid=135 描述 小 ...

  5. SQL2012通用分页存储过程

    --提取分页数据,返回总记录数 Createprocedure [dbo].[sp_Common_GetDataPaging_ReturnDataCount] ( @SqlString varchar ...

  6. 【模板】prim的heap优化

    简单的代码.. 时间复杂度为O((n + m)logn) 大部分情况下还是跑不过kruskal的,慎用. #include <cstdio> #include <queue> ...

  7. 【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值

    [bzoj1552/3506][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. ...

  8. [HNOI2015]实验比较 树形dp+组合数学

    在合并的时候有可以加等于,或者继续用小于, 比如siz[x]和siz[y]合并,小于的区间为max(siz[x],siz[y])<=k<=siz[x]+siz[y], 然后就是合并成多少个 ...

  9. php责任链模式

    php 责任链模式 又叫职责链模式.包含了一些命令对象和一些处理对象,每个处理对象决定它能处理那些命令对象,它也知道应该把自己不能处理的命令对象交下一个处理对象,该模式还描述了往该链添加新的处理对象的 ...

  10. POJ 2104 K-th Number【整体二分 + 树状数组】

    本来只是想学一下CDQ,还是先把整体二分搞懂一点. 这题窝几个月前分别用划分树,树套树,主席树和挑战上介绍的分桶法实现了一发(然而现在都忘得差不多了) 最快的是划分树,其次是主席树,然后是树套树,还有 ...