結果
| 問題 |
No.468 役に立つ競技プログラミング実践編
|
| コンテスト | |
| ユーザー |
siman
|
| 提出日時 | 2023-01-26 20:23:20 |
| 言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 379 ms / 2,000 ms |
| コード長 | 2,247 bytes |
| コンパイル時間 | 1,874 ms |
| コンパイル使用メモリ | 126,464 KB |
| 実行使用メモリ | 29,568 KB |
| 最終ジャッジ日時 | 2024-06-27 11:51:14 |
| 合計ジャッジ時間 | 8,269 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 31 |
| other | AC * 6 |
ソースコード
#include <iostream>
#include <stack>
#include <string.h>
#include <vector>
#include <climits>
using namespace std;
typedef vector <vector<int>> Graph;
vector<int> tsort(Graph G, int start, int end) {
vector<int> ret;
int degree[end];
memset(degree, 0, sizeof(degree));
for (int from = start; from < end; from++) {
for (int i = 0; i < G[from].size(); i++) {
int to = G[from][i];
degree[to]++;
}
}
stack<int> root;
for (int i = start; i < end; i++) {
if (degree[i] == 0) {
root.push(i);
}
}
while (!root.empty()) {
int from = root.top();
root.pop();
ret.push_back(from);
for (int i = 0; i < G[from].size(); i++) {
int to = G[from][i];
degree[to]--;
if (degree[to] == 0) {
root.push(to);
}
}
}
return ret;
}
struct Edge {
int to;
int cost;
Edge(int to = -1, int cost = -1) {
this->to = to;
this->cost = cost;
}
};
int main() {
int N, M;
cin >> N >> M;
Graph G(N);
vector<Edge> edges[N];
vector<Edge> reverse_edges[N];
for (int i = 0; i < M; ++i) {
int a, b, c;
cin >> a >> b >> c;
G[a].push_back(b);
edges[a].push_back(Edge(b, c));
reverse_edges[b].push_back(Edge(a, c));
}
vector<int> res = tsort(G, 0, N);
if (res.size() != N) {
// tsort failed.
cout << -1 << endl;
}
int dp[N];
memset(dp, 0, sizeof(dp));
int max_cost = 0;
for (int i = 0; i < res.size(); ++i) {
int v = res[i];
for (Edge &e : edges[v]) {
int n_cost = dp[v] + e.cost;
dp[e.to] = max(dp[e.to], n_cost);
max_cost = max(max_cost, dp[e.to]);
}
}
int min_cost[N];
for (int v = 0; v < N; ++v) {
min_cost[v] = INT_MAX;
}
for (int i = N - 1; i >= 0; --i) {
int v = res[i];
if (min_cost[v] == INT_MAX) {
min_cost[v] = dp[v];
}
for (Edge &e : reverse_edges[v]) {
int b_cost = min_cost[v] - e.cost;
min_cost[e.to] = min(min_cost[e.to], b_cost);
}
}
int buf_size = 0;
for (int v = 0; v < N; ++v) {
// fprintf(stderr, "v: %d, dp: %d, min: %d\n", v, dp[v], min_cost[v]);
if (dp[v] < min_cost[v]) ++buf_size;
}
cout << max_cost << " " << buf_size << "/" << N << endl;
return 0;
}
siman