結果

問題 No.468 役に立つ競技プログラミング実践編
ユーザー dnishdnish
提出日時 2018-07-02 19:07:07
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 367 ms / 2,000 ms
コード長 2,406 bytes
コンパイル時間 2,014 ms
コンパイル使用メモリ 184,352 KB
実行使用メモリ 33,932 KB
最終ジャッジ日時 2024-07-01 01:36:09
合計ジャッジ時間 8,493 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 7 ms
10,368 KB
testcase_01 AC 8 ms
10,300 KB
testcase_02 AC 8 ms
10,368 KB
testcase_03 AC 8 ms
10,284 KB
testcase_04 AC 8 ms
10,368 KB
testcase_05 AC 8 ms
10,312 KB
testcase_06 AC 7 ms
10,368 KB
testcase_07 AC 8 ms
10,296 KB
testcase_08 AC 8 ms
10,280 KB
testcase_09 AC 8 ms
10,368 KB
testcase_10 AC 7 ms
10,368 KB
testcase_11 AC 8 ms
10,304 KB
testcase_12 AC 8 ms
10,368 KB
testcase_13 AC 9 ms
10,496 KB
testcase_14 AC 10 ms
10,604 KB
testcase_15 AC 10 ms
10,504 KB
testcase_16 AC 10 ms
10,572 KB
testcase_17 AC 10 ms
10,496 KB
testcase_18 AC 10 ms
10,496 KB
testcase_19 AC 11 ms
10,496 KB
testcase_20 AC 10 ms
10,416 KB
testcase_21 AC 11 ms
10,496 KB
testcase_22 AC 10 ms
10,568 KB
testcase_23 AC 10 ms
10,536 KB
testcase_24 AC 356 ms
33,924 KB
testcase_25 AC 361 ms
33,920 KB
testcase_26 AC 360 ms
33,920 KB
testcase_27 AC 360 ms
33,932 KB
testcase_28 AC 363 ms
33,920 KB
testcase_29 AC 358 ms
33,920 KB
testcase_30 AC 358 ms
33,920 KB
testcase_31 AC 357 ms
33,932 KB
testcase_32 AC 364 ms
33,920 KB
testcase_33 AC 367 ms
33,920 KB
testcase_34 AC 111 ms
22,016 KB
testcase_35 AC 7 ms
10,408 KB
testcase_36 AC 9 ms
10,368 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include "bits/stdc++.h"
#define REP(i, n, N) for(ll i=(n); i<(N); i++)
#define RREP(i, n, N) for(ll i=(N-1); i>=n; i--)
#define CK(n, a, b) ((a)<=(n)&&(n)<(b))
#define ALL(v) (v).begin(),(v).end()
#define MCP(a,b) memcpy(b,a,sizeof(b))
#define p(s) cout<<(s)<<endl
#define p2(a, b) cout<<(a)<<" "<<(b)<<endl
#define v2(T) vector<vector<T>>
typedef long long ll;
using namespace std;
const ll mod = 1e9 + 7;
const ll inf = 1e18;

const ll NODE_SIZE = 101010;
ll N;
ll M;
vector<vector<pair<ll, ll>>> edge(NODE_SIZE);   //<ノード, コスト>
vector<vector<pair<ll, ll>>> edge2(NODE_SIZE);   //<ノード, コスト>
ll d[NODE_SIZE];   //始点ノードからノードiへの最短距離
ll start;  //開始ノード番号
ll rev[NODE_SIZE]; //一個前を覚える

vector<ll> tsort(vector<vector<pair<ll, ll>>> g) {
    ll k = 0;
    vector<ll> in(N,0);
    vector<ll> ord(N);
    // 自分に繋がっているエッジの次数カウント
    for (auto es : g)
        for (auto e : es) in[e.first]++;
    queue<ll> q;
    for (ll i = 0; i < N; ++i)
        if (in[i] == 0) q.push(i);
    while (!q.empty()) {
        ll node = q.front();
        q.pop();
        ord[k++] = node;
        for (auto e : g[node])
            if (--in[e.first] == 0){
                q.push(e.first); //使ってもいいノードの追加
            }

    }
    return *max_element(in.begin(), in.end()) == 0 ? ord : vector<ll>();
}

int main(){
    cin>>N>>M;
    ll A,B,C;
    REP(i,0,M){
        cin>>A>>B>>C;
        edge[A].emplace_back(B,C);
        edge2[B].emplace_back(A,C);
    }
    vector<ll> route = tsort(edge);
    vector<ll> D(N, -inf);
    D[route[0]] = 0;
    //最早
    for(auto v: route) {
        for(auto uc: edge[v]) {
            ll node = uc.first;
            ll c = uc.second;
            D[node] = max(D[node], D[v] + c); //一番時間がかかる有向辺
        }
    }
    ll T = D[route[N-1]];
    vector<bool> used(N,0);
    used[route[N-1]] = 1;
    //最遅
    reverse(route.begin(), route.end());
    for(auto v: route) {
        if (!used[v]) continue;
        for(auto uc: edge2[v]) {
            ll node = uc.first;
            ll cost = uc.second;
            if (D[node] + cost == D[v]) {
                used[node] = 1;
            }
        }
    }
    ll P = count(used.begin(), used.end(),true);
    P = N-P;
    printf("%lld %lld/%lld\n", T, P, N);

    return 0;
}
0