BZOJ1016 && JSOI2008] 最小生成树计数
题目链接: 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 && JSOI2008] 最小生成树计数的更多相关文章
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
- BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数
题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...
- [BZOJ1016][JSOI2008]最小生成树计数(结论题)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E ...
- [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 【最小生成树】BZOJ1016: [JSOI2008]最小生成树计数
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)
传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...
- [BZOJ1016][JSOI2008]最小生成树计数 最小生成树 搜索
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如 ...
随机推荐
- python 装饰器模拟京东登陆
要求: 1.三个页面:主页面(home).书店(book).金融页面(finance)2.有两种登陆方式:主页面和书店页面使用京东账户登陆,金融页面使用微信账户登录2.输入:1 ,进入主页面,以此类推 ...
- [jzoj5073 GDOI2017第二轮模拟] 影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...
- pispice中pispice文件夹下模型的描述
VPULSE: 利用PSpice进行仿真时,用VPULSE产生方波,VPULSE在SOURSE库中,有七个参数: V1:低电平,如-5V: V2:高电平,如+5V: TD:第一个脉冲相对于0时刻的延迟 ...
- MySQL报错The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents
参考资料:https://blog.csdn.net/qq_37630354/article/details/82814330 在property里加上最后这个参数即可
- HDU 5421 Victor and String
Victor and String Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on HDU. Orig ...
- Leetcode 310.最小高度树
最小高度树 对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们 ...
- php 面向对象 (类 对象)
//面向对象//什么是面向对象//面向过程//什么是对象?//一切皆是对象//类//由对象抽象化//造类//class Ren//{ //构造方法 - - 写不写都存在//类的初始化方法 //构造方法 ...
- hdu1856 选出更多的孩子
题目大意: 老师选取2个学生对应的号码,这两人视作朋友,同时朋友的朋友也可以看成自己的朋友. 最后老师选出一个人数最多的朋友圈. 这里学生的人数不大于10^7,所以操作时需要极为注意,操作步数能省则省 ...
- mybatis使用步骤
1.创建config.xml文件.设置环境.数据源等: 2.设置mapper.xml文件.写sql:下面图中的resultType属性经常会替换为resultMap,不过需要加入<resultM ...
- 2016 年末 QBXT 入学测试
P4744 A’s problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算一次成绩.参与享优惠 描述 这是一道有背 ...