Submission #403306

#TimeUsernameProblemLanguageResultExecution timeMemory
403306Haruto810198Travelling Merchant (APIO17_merchant)C++17
0 / 100
49 ms5572 KiB
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define double long double

#define FOR(i,l,r,d) for(int i=(l);i<=(r);i+=(d))
#define szof(x) ((x).size())

#define vi vector<int>
#define pii pair<int,int>

#define F first
#define S second

#define pb push_back
#define eb emplace_back
#define mkp make_pair

const int INF = 1e14;
const int MOD = 1000000007;
const int mod = 998244353;
const double eps = 1e-12;

//#pragma GCC optimize("Ofast")

const int NMAX = 101;
const int MMAX = 9901;
const int CMAX = 1001;
/// c = n. of items

int n, m, c;
int buy[NMAX][CMAX], sell[NMAX][CMAX];
/// buy[i][j] : buy item j at market i

int dt[NMAX][NMAX], profit[NMAX][NMAX], weight[NMAX][NMAX];
int sp[NMAX][NMAX];

int res;

bool has_non_pos_cyc(int T){

    /// check if the graph has a non-positive cycle

    /// init
    FOR(i,1,n,1){
        FOR(j,1,n,1){
            sp[i][j] = weight[i][j];
        }
    }

    /// shortest path
    FOR(k,1,n,1){
        FOR(i,1,n,1){
            FOR(j,1,n,1){
                sp[i][j] = min(sp[i][j], sp[i][k] + sp[k][j]);
                if(sp[i][j]<-1000*INF){ /// prevent overflow
                    return 1;
                }
            }
        }
    }

    /// check if cycle(i->j->i)<=0 for all i!=j
    FOR(i,1,n,1){
        FOR(j,1,n,1){
            if(i!=j and sp[i][j]+sp[j][i]<=0){
                return 1;
            }
        }
    }

    return 0;

}

bool check(int T){

    /// check if new graph has a non-negative cycle
    /// negate all edges -> check if the graph has a non-positive cycle
    FOR(i,1,n,1){
        FOR(j,1,n,1){
            if(dt[i][j]!=INF and profit[i][j]!=-INF){
                weight[i][j] = -profit[i][j] + T*dt[i][j];
            }
            else{
                weight[i][j] = INF;
            }
        }
    }

    return (has_non_pos_cyc(T));

}

signed main(){

    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    /// input
    cin>>n>>m>>c;

    FOR(i,1,n,1){
        FOR(j,1,c,1){
            cin>>buy[i][j]>>sell[i][j];
        }
    }

    /// dt, profit

    FOR(i,1,n,1){
        FOR(j,1,n,1){
            dt[i][j] = INF; /// dt = INF : no edge
        }
        dt[i][i] = 0;
    }

    FOR(i,1,m,1){
        int u, v, w;
        cin>>u>>v>>w;
        dt[u][v] = w;
    }

    FOR(i,1,m,1){
        FOR(j,1,m,1){
            profit[i][j] = 0;
            FOR(k,1,c,1){
                if(buy[i][k]!=-1 and sell[j][k]!=-1){
                    profit[i][j] = max(profit[i][j], -buy[i][k] + sell[j][k]);
                }
            }
        }
        profit[i][i] = 0;
    }

    /// BS for the answer
    int L=0, R=1e9+1, mid;
    while(L<R){
        mid = (L+R+1) / 2;
        if(check(mid)){
            L = mid;
        }
        else{
            R = mid-1;
        }
    }

    res = L;

    cout<<res<<'\n';

    return 0;

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...