結果

問題 No.468 役に立つ競技プログラミング実践編
ユーザー dnishdnish
提出日時 2018-07-02 19:07:07
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 352 ms / 2,000 ms
コード長 2,406 bytes
コンパイル時間 1,731 ms
コンパイル使用メモリ 180,108 KB
実行使用メモリ 34,060 KB
最終ジャッジ日時 2023-09-13 17:00:17
合計ジャッジ時間 8,466 ms
ジャッジサーバーID
(参考情報)
judge11 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 7 ms
10,136 KB
testcase_01 AC 6 ms
10,104 KB
testcase_02 AC 7 ms
10,192 KB
testcase_03 AC 7 ms
10,104 KB
testcase_04 AC 8 ms
10,260 KB
testcase_05 AC 7 ms
10,052 KB
testcase_06 AC 8 ms
10,248 KB
testcase_07 AC 7 ms
10,084 KB
testcase_08 AC 7 ms
10,124 KB
testcase_09 AC 8 ms
10,152 KB
testcase_10 AC 7 ms
10,172 KB
testcase_11 AC 7 ms
10,060 KB
testcase_12 AC 7 ms
10,064 KB
testcase_13 AC 7 ms
10,128 KB
testcase_14 AC 9 ms
10,316 KB
testcase_15 AC 9 ms
10,328 KB
testcase_16 AC 10 ms
10,504 KB
testcase_17 AC 9 ms
10,440 KB
testcase_18 AC 10 ms
10,452 KB
testcase_19 AC 9 ms
10,392 KB
testcase_20 AC 9 ms
10,404 KB
testcase_21 AC 9 ms
10,348 KB
testcase_22 AC 10 ms
10,448 KB
testcase_23 AC 9 ms
10,432 KB
testcase_24 AC 352 ms
33,580 KB
testcase_25 AC 336 ms
33,736 KB
testcase_26 AC 337 ms
33,744 KB
testcase_27 AC 336 ms
33,740 KB
testcase_28 AC 337 ms
33,864 KB
testcase_29 AC 338 ms
33,764 KB
testcase_30 AC 338 ms
33,824 KB
testcase_31 AC 350 ms
34,060 KB
testcase_32 AC 340 ms
33,612 KB
testcase_33 AC 340 ms
33,672 KB
testcase_34 AC 105 ms
21,812 KB
testcase_35 AC 8 ms
10,276 KB
testcase_36 AC 8 ms
10,224 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