# 【CSES】1673. High Score ## [題目連結](https://cses.fi/problemset/task/1673) ## **時間複雜度** * $O(|V||E|$ x $(V+E))$ ## **解題想法** 這一題是一個非常麻煩的題目,需要考慮到所有狀況才能拿到 <span style="color: green">**AC**</span> ### 需要注意的測資 **特殊圖** 對於特殊圖的解法就是把路反向之後看終點走到起點前會不會DFS到環,如果有的話特判掉一些特殊情況就然後輸出 $-1$ 就可以了 第一類,會影響到答案的環 :::spoiler 1. 有可能會流回到起點的圖 ![](https://hackmd.io/_uploads/HkTn0nPon.png) ::: <br> :::spoiler 2. 終點在環上的圖 ![](https://hackmd.io/_uploads/H1hsxpDsh.png) ::: <br> :::spoiler 3. 起點在環上的圖 ![](https://hackmd.io/_uploads/H1UXQ6Dj2.png) ::: <br> 第二類,不會影響到答案的環 :::spoiler 1. 有環但不需要走 ![](https://hackmd.io/_uploads/HyJUGavi2.png) ::: ## **完整程式** ```cpp= /* Question : CSES 1673. High Score */ #include<bits/stdc++.h> using namespace std; #define opt ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define mem(x, value) memset(x, value, sizeof(x)); #define pii pair<int, int> #define pdd pair<double, double> #define f first #define s second #define int long long const auto dir = vector< pair<int, int> > { {1, 0}, {0, 1}, {-1, 0}, {0, -1} }; const int MAXN = 2e5 + 50; const int Mod = 1e9 + 7; int n, m, a, b, w, r, t, tmp; bool flag = false, fg, times[MAXN]; vector<pair<int, pii>> edge; vector<vector<int>> graph, negG; int dis[MAXN], negc[MAXN]; int dfs( int root ){ if( negc[root] == true ) return -1; if( root == 1 && negG[root].size() == 0 ) return (-1 * dis[n]); for( auto i : negG[root] ){ if( negc[i] == true ) return -1; if( times[i] == true ) continue; times[i] = true; tmp = dfs(i); if( tmp == (-1 * dis[n]) ) break; if( tmp == -1 ) return -1; } return (-1 * dis[n]); } int bell( int root ){ for( int i = 1 ; i <= n ; i++ ) dis[i] = 1e15; dis[root] = 0; for( int i = 1 ; i <= n ; i++ ){ for(auto e : edge ){ int w = e.f; int a = e.s.f; int b = e.s.s; if( dis[a] + w < dis[b] ){ if( i == n-1 ){ flag = true; negc[a] = true; negc[b] = true; } dis[b] = dis[a] + w; } } } if( flag ) return dfs(n); else return (-1 * dis[n]); } signed main(){ opt; cin >> n >> m; graph.resize(n+5); negG.resize(n+5); for( int i = 0 ; i < m ; i++ ){ cin >> a >> b >> w; edge.push_back({(-1 * w), {a, b}}); negG[b].push_back(a); graph[a].push_back(b); } if( m == 1 && n > 1 ) cout << -1 * edge[0].first << "\n"; else if( n == 1 && m == 1 ){ if( edge[0].f < 0 ) cout << "-1\n"; else cout << "0\n"; } else cout << bell(1) << "\n"; } ```