トピックポータル
https://lydsy.com/JudgeOnline/problem.php?id=4386
問題の解決策
一つは見ることができ、隣接行列高速電力です。
しかし、ここで右側がされていない(1 \)を\します。しかし、我々は、右端まで、見つけることができます\(3 \) 。しかし、エッジの多くの数は、解体側には適していません、それのポイントを分割します。以下のために(Y軸\にX \)\側、作成する\({wが- Y_するX_0 1} \ \)の側面を、\(W \)は右側です。
そして、その上にマトリックスの設立に。私たちが頼りにする必要があるため、\(私は\)あなたは再びリングをこの時点自身から新規ノード、この時点でも有向エッジに各ポイントを、作成することができるように、ステップの前にどのように多くのパスの合計。
そして、前処理された\(B_i \)消えた\(2 ^ I \)ステップ行列が直接出て掛け、それに答えます。
ここで、コードは、行列乗算の複雑さは、\(O(N ^ 3)\) 、総乗算\(Oは(\ Kログ) \) 回ので、合計時間複雑である\(O(N ^ 3 \ Kログ)\) 。
#include<bits/stdc++.h>
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
template<typename I>
inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
}
const int N = 40 * 3 + 7;
int n, m;
ll k;
struct Matrix {
ll a[N][N];
inline Matrix() { memset(a, 0, sizeof(a)); }
inline Matrix operator * (const Matrix &b) {
Matrix c;
for (int k = 0; k <= n; ++k)
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
c.a[i][j] += a[i][k] * b.a[k][j];
return c;
}
inline void print() const {
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= n; ++j) dbg("%lld ", a[i][j]);
dbg("\n");
}
}
} A, B[N];
inline bool isfull(const Matrix &a) {
ll cnt = 0;
for (int i = 1; i <= n / 3; ++i) {
cnt += a.a[i][0] - 1;
if (cnt >= k) return 1;
}
return 0;
}
inline void work() {
n = n * 3, B[0] = A;
int lim = 0;
for (int i = 1; i <= 70; ++i) {
B[i] = B[i - 1] * B[i - 1];
++lim;
if (isfull(B[i])) break;
}
if (!isfull(B[lim--])) {
puts("-1");
return;
}
memset(A.a, 0, sizeof(A.a));
for (int i = 0; i <= n; ++i) A.a[i][i] = 1;
ll ans = 0;
for (int i = lim; ~i; --i) {
const Matrix &tmp = A * B[i];
if (!isfull(tmp)) A = tmp, ans += 1ll << i;
}
printf("%lld\n", ans);
}
inline void init() {
read(n), read(m), read(k);
for (int i = 1; i <= m; ++i) {
int x, y, z;
read(x), read(y), read(z);
if (z == 1) ++A.a[x][y];
if (z == 2) ++A.a[x][y + n];
if (z == 3) ++A.a[x][y + n * 2];
}
for (int i = 1; i <= n; ++i) A.a[i][0] = A.a[i + n][i] = A.a[i + n * 2][i + n] = 1;
A.a[0][0] = 1;
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}