This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
constexpr int NMAX = 105;
constexpr int MMAX = 10002;
constexpr int KMAX = 1005;
constexpr LL INF = 1LL * 1e17;
struct Muchie {
    int x, y;
    LL cost;
};
Muchie Edge[MMAX];
int N, M, K;
LL B[NMAX][NMAX];
LL S[NMAX][NMAX];
LL profit[NMAX][NMAX];
LL timp[NMAX][NMAX];
bool can[NMAX][NMAX];
vector <PII> G[NMAX];
void Read () {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> N >> M >> K;
    for (int i = 1; i <= N; ++ i )
        for (int j = 1; j <= K; ++ j )
            cin >> B[i][j] >> S[i][j];
    for (int i = 1; i <= M; ++ i ) {
        cin >> Edge[i].x >> Edge[i].y >> Edge[i].cost;
        G[Edge[i].x].push_back({Edge[i].y, Edge[i].cost});
    }
}
void Reach (int Start) {
    queue <int> Q;
    Q.push(Start);
    for (int i = 1; i <= N; ++ i )
        timp[Start][i] = INF;
    timp[Start][Start] = 0;
    while (!Q.empty()) {
        int nod = Q.front();
        Q.pop();
        can[Start][nod] = true;
        for (auto it : G[nod]) {
            int to = it.first;
            if (timp[Start][to] > timp[Start][nod] + it.second) {
                timp[Start][to] = timp[Start][nod] + it.second;
                Q.push(to);
            }
        }
    }
}
void Precompute () {
    for (int i = 1; i <= N; ++ i ) {
        for (int j = 1; j <= N; ++ j ) {
            if (i == j) continue;
            profit[i][j] = 0;
            for (int k = 1; k <= K; ++ k )
                profit[i][j] = max(profit[i][j], S[j][k] - B[i][k]);
        }
    }
    for (int i = 1; i <= N; ++ i )
        Reach(i);
}
LL ans[NMAX];
int Lg[NMAX];
bool use[NMAX];
LL TrueCost[NMAX][NMAX];
bool Good (LL cost) {
    for (int i = 1; i <= N; ++ i ) {
        for (int j = 1; j <= N; ++ j ) {
            if (i == j) continue;
            if (!can[i][j]) continue;
            TrueCost[i][j] = cost * timp[i][j] - profit[i][j];
        }
    }
    ///suma profit / suma timp >= cost
    ///suma profit - cost * suma timp >= 0
    ///cost * suma timp - suma profit <= 0
    ///Exista ciclu negativ ?
	
    for (int i = 1; i <= N; ++ i ) 
        ans[i] = INF;
    ans[1] = 0;
    Lg[1] = 1;
    queue <int> Q;
    Q.push(1);
    use[1] = true;
    while (!Q.empty()) {
        int nod = Q.front();
        Q.pop();
        use[nod] = false;
        for (int i = 1; i <= N; ++ i ) {
            if (!can[nod][i]) continue;
            if (ans[i] > ans[nod] + TrueCost[nod][i]) {
                ans[i] = ans[nod] + TrueCost[nod][i];
                Lg[i] = Lg[nod] + 1;
                if (Lg[i] > N) {
                    return true;
                }
                if (!use[i]) {
                    use[i] = true;
                    Q.push(i);
                }
            }
        }
    }
    return false;
}
void Solve () {
    LL st = 1, dr = 1000000000;
    LL ans = 0;
    while (st <= dr) {
        LL mij = (st + dr) / 2;
        if (Good(mij)) {
            st = mij + 1;
            ans = mij;
        }
        else dr = mij - 1;
    }
    cout << ans << '\n';
}
int main () {
    Read();
    Precompute();
    Solve();
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |