loop negative matrix multiplication bzoj4773 +

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=4773

answer

Loop negative minimum length, equivalent to the minimum \ (len \) such that there is a point from the \ (I \) to present himself a length \ (\ leq len \) minus right path.

In order to (\ leq len \) \ into \ (= len \) , we can give each side a point to establish a right to \ (0 \) from the ring.

Therefore, considering the adjacency matrix multiplication, passes between the two points to maintain \ (2 ^ i \) edges of the shortest.

Doubling time judge go so many steps there are no negative ring on it.

Finally, the end of the judge once again, to prevent no solution.


Time complexity \ (O (n-^. 3 \ log n-) \) .

#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 = 300 + 7;
const int INF = 0x3f3f3f3f;

int n, m;

struct Matrix {
    int a[N][N];
    
    inline Matrix() { memset(a, 0x3f, sizeof(a)); }
    inline Matrix(const int &x) {
        memset(a, 0x3f, sizeof(a));
        for (int i = 1; i <= n; ++i) a[i][i] = x;
    }
    
    inline Matrix operator * (const Matrix &b) {
        Matrix c;
        for (int k = 1; k <= n; ++k)
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)
                    smin(c.a[i][j], a[i][k] + b.a[k][j]);
        return c;
    }
} A, B[9];

inline void work() {
    B[0] = A, A = Matrix(0);
    for (int i = 1; i < 9; ++i) B[i] = B[i - 1] * B[i - 1];
    int ans = 0;
    for (int i = 8; ~i; --i) {
        Matrix C = A * B[i];
        int mn = INF;
        for (int j = 1; j <= n; ++j) smin(mn, C.a[j][j]);
        if (mn >= 0) A = C, ans += 1 << i;
    }
    A = A * B[0];
    int mn = INF;
    for (int j = 1; j <= n; ++j) smin(mn, A.a[j][j]);
    if (mn >= 0) puts("0");
    else printf("%d\n", ans + 1);
}

inline void init() {
    read(n), read(m);
    int x, y, z;
    A = Matrix(0);
    for (int i = 1; i <= m; ++i) read(x), read(y), read(z), A.a[x][y] = z;
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/bzoj4773.html