题目链接:

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. 第二天,学习if,变量,注释

    zz_age = 31guss_age=int(input("input your answer:"))if guss_age == zz_age: print ("Yo ...

  2. 有上下界的网络流 loj115 loj116 loj 117

    参考文章 无源汇有上下界的可行流 有源汇有上下界的最大流 有源汇有上下界的最小流 无源汇有上下界可行流 以 loj115 为例. 剥离出必要边与自由边. #include <iostream&g ...

  3. 大数据学习——hadoop2.x集群搭建

    1.准备Linux环境 1.0先将虚拟机的网络模式选为NAT 1.1修改主机名 vi /etc/sysconfig/network NETWORKING=yes HOSTNAME=itcast ### ...

  4. UVALive 2957 Bring Them There

    Bring Them There Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. O ...

  5. xtu summer individual 1 A - An interesting mobile game

    An interesting mobile game Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on H ...

  6. zoj 2807 Electrical Outlets

    Electrical Outlets Time Limit: 2 Seconds      Memory Limit: 65536 KB Roy has just moved into a new a ...

  7. 【CSS】position relative 用法

    Relative是position的一个属性,是相对定位. position的默认值是static,(也就是说对于任意一个元素,如果没有定义它的position属性,那么它的position:stat ...

  8. HDU-1041-Computer Transformation,大数递推,水过~~

                                                                                  Computer Transformatio ...

  9. [Kubernetes]Volume

    容器技术使用rootfs机制和Mount Namespace,构建出一个同宿主机完全隔离开的文件系统环境 那容器里进程新建的文件,怎么样才能让宿主机获取到?宿主机上的文件和目录,怎么样才能让容器里的进 ...

  10. hdu 3371

    #include<stdio.h> #include<stdlib.h> #define N 501 struct node { int x,y,dis; }road[N*N] ...