結果
| 問題 |
No.2712 Play more!
|
| コンテスト | |
| ユーザー |
blue_jam
|
| 提出日時 | 2024-03-31 21:53:27 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 4,447 bytes |
| コンパイル時間 | 4,036 ms |
| コンパイル使用メモリ | 257,156 KB |
| 最終ジャッジ日時 | 2025-02-20 18:26:28 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | RE * 3 |
| other | RE * 33 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
using ll = long long;
using mint = modint998244353;
/**
* @file
* ### グラフの要素
* グラフは各頂点から出て行く辺をリストとして保持する隣接リスト表現と各頂点間に辺が存在する情報を記録する隣接行列表現がある.
* それぞれ利点があるので状況に応じて使い分けること.
*
* <dl>
* <dt>隣接リスト</dt><dd>頂点を基準に考えればいいときに有向.重複辺も扱える.</dd>
* <dt>隣接行列</dt><dd>@f$O(E)@f$ が @f$O(V^2)@f$ になる.密グラフや,頂点数が少ないグラフについて効率よく扱える.重複辺を扱いにくい.</dd>
* </dl>
*
* ### ソースコード
*
* @include graph.cpp
*
* Edgeのless演算子のオーバーロードで,大きいほうが左辺のときにtrueを返すようにしている.
* これはpriority_queueで,weightの小さいほうを先に取り出すときの工夫である.
* 気に入らない場合は,greater演算子をオーバーロードし,priority_queueを以下のように宣言する.
*
* @code
* priority_queue<Edge>, vector<Edge>, greater<Edge>> Q;
* @endcode
*/
typedef ll Weight;
struct Edge{
int from, to;
Weight weight;
int rev; // 無向グラフの対の辺
Edge(int from, int to, Weight weight) :
from(from), to(to), weight(weight) { }
Edge(int from, int to, Weight weight, int rev) :
from(from), to(to), weight(weight), rev(rev){ }
};
bool operator < (const Edge &a, const Edge &b){
if(a.weight != b.weight) return a.weight > b.weight;
if(a.from != b.from) return a.from > b.from;
return a.to > b.to;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void addFlowEdge(Graph &g, int a, int b, Weight c){
g[a].push_back(Edge(a, b, c, g[b].size()));
g[b].push_back(Edge(b, a, 0, g[a].size() - 1));
}
void addUndirectedEdge(Graph &g, int a, int b, Weight c){
g[a].push_back(Edge(a, b, c, g[b].size()));
g[b].push_back(Edge(b, a, c, g[a].size() - 1));
}
const ll INF = 1e17;
/**
* bellmanFordでは最短路を計算する.
*
* bellmanFordにおいて,distに-INFと記録された頂点以外にも,負の閉路の影響を受ける頂点があることがある.-INFと記録された頂点から到達できるすべての頂点は負の閉路の影響を受ける.(要確認)
*
* @param g 最短路を求めたいグラフ
* @param s 始点
* @param dist 距離を記録する.経路がない場合はINF,そこへ到達するまでに負の閉路が含まれることがわかっていれば-1
* @param prev 経路復元用の1つ前の位置を示す配列
* @return 負の閉路が含まれているか
*/
bool bellmanFord(const Graph &g, int s, vector<Weight> &dist, vector<int> &prev){
int n = g.size();
bool negativeLoop = false;
dist.assign(n, INF); dist[s] = 0;
prev.assign(n, -1);
for(int k = 0; k < n; ++k){
for(int v = 0; v < 2 * n; ++v){
for(Edges::const_iterator i=g[v].begin(); i != g[v].end(); ++i){
if(dist[i -> from] != INF && dist[i -> to] > dist[i -> from] + i -> weight){
if (dist[i -> from] == -INF) {
dist[i -> to] = -INF;
} else {
dist[i -> to] = dist[i -> from] + i-> weight;
}
prev[i -> to] = i -> from;
if(k == n - 1){
dist[i -> to] = -INF;
negativeLoop = true;
}
}
}
}
}
return negativeLoop;
}
void solveE() {
ll N, M;
cin >> N >> M;
vector<ll> A(N);
for (ll i = 0; i < N; i++) {
cin >> A[i];
}
Graph g(N);
for (ll i = 0; i < M; i++) {
ll a, b, c;
cin >> a >> b >> c;
a--; b--;
g[a].push_back(Edge(a, b, c - A[b]));
}
vector<ll> dist;
vector<int> prev;
bool negativeLoop = bellmanFord(g, 0, dist, prev);
if (dist[N - 1] == -INF) {
cout << "inf" << endl;
} else {
cout << A[0] - dist[N - 1] << endl;
}
}
int main() {
ios::sync_with_stdio(false);
solveE();
return 0;
}
blue_jam