标签:amp 离散 pre end 连通图 ase res int operator
离散数学里面好像有一个连通图的可达矩阵,通过矩阵的幂乘找到该点每一步可到达的点
该题明显是k步后到了哪些点
int mod;
struct mat {
int data[110][110] = { 0 };
int n = 110;
mat() {};
mat(int n) : n(n) {};
mat(int d, int x) {
n = d;
for (int i = 0; i < n; ++i) data[i][i] = x;
}
void disp(int n) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
printf("%d%c", data[i][j], j == n - 1 ? ‘\n‘ : ‘ ‘);
}
int* operator [](int i) {
return data[i];
}
mat operator * (mat& other) {
mat res(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
res[i][j] += 1ll * data[i][k] * other[k][j] % mod;
if (mod <= res[i][j]) res[i][j] -= mod;
}
}
}
return res;
}
};
mat qpow(mat base, ll n) {
mat res(base.n, 1);
while (n) {
if (n & 1) res = res * base;
base = base * base;
n >>= 1;
}
return res;
}
signed main() {
int n, m, st, ed;
ll k;
scanf("%d %d %d", &n, &m, &mod);
scanf("%lld %d %d", &k, &st, &ed);
mat g(n);
for (int i = 0; i < m; ++i) {
int u, v; scanf("%d %d", &u, &v);
g[u][v] = 1;
g[v][u] = 1;
}
mat ans = qpow(g, k);
if (ans[st][ed] != 0) printf("%d\n", ans[st][ed]);
else {
if (mod != 1e9 + 7) mod = 1e9 + 7;
else mod = 1e9 + 9;
ans = qpow(g, k);
puts(ans[st][ed] == 0 ? "Mendes will sleep in peace." : "0");
}
return 0;
}
标签:amp 离散 pre end 连通图 ase res int operator
原文地址:https://www.cnblogs.com/wanshe-li/p/14492588.html