https://en.wikipedia.org/wiki/Kirchhoff's_theorem
4 5
1 3
1 4
2 3
2 4
3 4
2 0 -1 -1
0 2 -1 -1
-1 -1 3 -1
-1 -1 -1 3
2 0 -1
0 2 -1
-1 -1 3
223 - 2 - 2 = 8
无向图是有向图的一个特殊情况
有向图
a[i][j] = 边数的相反数 (i!=j)
a[i][j] = 入度 (i==j)
可以结合Matrix-Tree Theorem计算有向图的欧拉回路个数
https://www.luogu.com.cn/problem/P6178
给定一张 个结点 条边的带权图(可能为无向图,可能为有向图)。
定义其一个生成树 的权值为 中所有边权的乘积。
求其所有不同生成树的权值之和,对 取模。
注意:
本题中,有向图的生成树指的是 以 为根的外向树;
两棵生成树 不同,当且仅当存在存在一条边 ,满足 。
第一行:三个整数 ,分别表示图的结点数量,边的数量和图的类型( 时为无向图, 时为有向图)。
接下来 行:每行三个整数 。
如果 ,表示 之间有一条权值为 的无向边;
如果 ,表示从 到 有一条权值为 的有向边。
第一行:一个整数 ,表示给定的图的生成树权值和对 取模的结果。
5 8 0
2 3 1
1 2 3
4 5 1
4 2 2
3 5 2
3 4 3
3 4 1
3 3 5
144
5 9 1
1 2 3
3 2 1
1 3 1
2 4 2
3 5 1
4 3 4
3 5 1
5 4 1
4 4 6
72
【样例 解释】
样例 中的无向图如左图所示:
右图为其一个权值为 的生成树的例子。
【样例 解释】
样例 中的有向图如左图所示:
右图为其一个权值为 的生成树(以 为根的外向树)的例子。
【数据范围】
对于 的数据:。
对于测试点 ,;对于测试点 ,。
图中 可能 存在重边和自环,重边算作多条边。
#include <bits/stdc++.h> using namespace std; const int mod = 1000000007; int n, m, t, u, v, w; int a[300][300]; int work() { int ans = 1; for (int i = 1; i < n; i++) { for (int j = i + 1; j < n; j++) { while (a[j][i]) { int t = a[i][i] / a[j][i]; for (int k = 1; k < n; k++) { a[i][k] = (a[i][k] - (long long)a[j][k] * t) % mod; } swap(a[i], a[j]); ans = -ans; } } ans = (long long)ans * a[i][i] % mod; } return (ans + mod) % mod; } int main() { scanf("%d%d%d", &n, &m, &t); for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); u--; v--; a[u][v] = (a[u][v] + mod - w) % mod; a[v][v] = (a[v][v] + w) % mod; if (!t) { a[v][u] = (a[v][u] + mod - w) % mod; a[u][u] = (a[u][u] + w) % mod; } } printf("%d\n", work()); return 0; }
https://www.luogu.com.cn/problem/P4455
当今社会,在社交网络上看朋友的消息已经成为许多人生活的一部分。通常,一个用户在社交网络上发布一条消息后,他的好友们也可以看见这条消息,并可能转发。转发的消息还可以继续被人转发,进而扩散到整个社交网络中。
在一个实验性的小规模社交网络中我们发现,有时一条热门消息最终会被所有人转发。为了研究这一现象发生的过程,我们希望计算一条消息所有可能的转发途径有多少种。为了编程方便,我们将初始消息发送者编号为 ,其他用户编号依次递增。
该社交网络上的所有好友关系是已知的,也就是说对于 两个用户,我们知道 用户可以看到 用户发送的消息。注意可能存在单向的好友关系,即 能看到 的消息,但 不能看到 的消息。
还有一个假设是,如果某用户看到他的多个好友转发了同一条消息,他只会选择从其中一个转发,最多转发一次消息。从不同好友的转发,被视为不同的情况。
如果用箭头表示好友关系,下图展示了某个社交网络中消息转发的所有可能情况。(初始消息是用户 发送的,加粗箭头表示一次消息转发)
答案对 取模。
第一行有一个整数,表示用户的数量 。
第二行有一个整数,表示好友关系数目 。
接下来 行,每行两个整数 ,表示一组好友关系,即用户 可以看到用户 发送的信息。
输出一行一个整数表示答案对 取模的结果。
4
7
2 1
3 1
1 3
2 3
3 2
4 3
4 2
6
数据规模与约定
#include <bits/stdc++.h> using namespace std; const int mod = 10007; int n, m, u, v; int a[300][300]; int work() { int ans = 1; for (int i = 1; i < n; i++) { for (int j = i + 1; j < n; j++) { while (a[j][i]) { int t = a[i][i] / a[j][i]; for (int k = 1; k < n; k++) { a[i][k] = (a[i][k] - (long long)a[j][k] * t) % mod; } swap(a[i], a[j]); ans = -ans; } } ans = (long long)ans * a[i][i] % mod; } return (ans + mod) % mod; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < m; i++) { scanf("%d%d", &v, &u); u--; v--; a[u][v]--; a[v][v]++; } printf("%d\n", work()); return 0; }