- 卡車說可以從一個假點開始做 SSSP,也就是將所有點的距離都先設成 0。
- 我的寫法複雜度看起來不好,感覺假解了,但想不到該怎麼改,可能會 TLE。
- 想了一個確定複雜度是 O(VE) 的解,將整張圖做 SCC,形成一個 DAG,從每個 in-degree 為 0 的 SCC 選一個點做 DFS。
1#include<bits/stdc++.h>
2using namespace std;
3typedef long long ll;
4typedef pair<int, ll> pii;
5#define pb push_back
6vector<int> ans;
7vector<vector<pii>> G;
8vector<bool> visit;
9vector<bool> use;
10vector<ll> dis;
11int dfs(int v) {
12 use[v] = visit[v] = true, ans.pb(v);
13 for (pii e : G[v]) {
14 int u = e.first;
15 ll w = e.second;
16 if (dis[u] <= dis[v] + w) continue;
17 dis[u] = dis[v] + w;
18 if (visit[u]) return u;
19 int ret = dfs(u);
20 if (ret) return ret;
21 }
22 visit[v] = false, ans.pop_back();
23 return 0;
24}
25int solve(int n) {
26 for (int i = 1, ret; i < n; i++)
27 if (!use[i] && (ret = dfs(i))) return ret;
28 return 0;
29}
30bool SPFA (int n) {
31 queue<int> q;
32 vector<int> cnt(n);
33 vector<bool> inque(n);
34 for (int i = 1; i < n; i++) {
35 if (cnt[i]) continue;
36 inque[i] = 1, q.push(i);
37 while (!q.empty()) {
38 int u = q.front(); q.pop();
39 inque[u] = false;
40 for (pii p : G[u]) {
41 int uu = p.first; ll w = p.second;
42 if (dis[uu] > dis[u] + w) {
43 dis[uu] = dis[u] + w, cnt[uu]++;
44 if (cnt[uu] > n) return false;
45 if (!inque[uu]) inque[uu] = true, q.push(uu);
46 }
47 }
48 }
49 } return true;
50}
51int main() {
52 ios_base::sync_with_stdio(0); cin.tie(0);
53 int n, m; cin >> n >> m; n++;
54 G.resize(n), visit.resize(n), dis.resize(n), use.resize(n);
55 for (int i = 0; i < m; i++) {
56 int a, b; ll c; cin >> a >> b >> c;
57 if (a == b && c < 0) // loop
58 cout << "YES\n" << a << ' ' << b << "\n";
59 G[a].pb(pii(b, c));
60 }
61 if (SPFA(n)) { cout << "NO\n"; return 0;}
62 int v = solve(n), flag = 0;
63 cout << "YES\n";
64 for (int x : ans) {
65 if (x == v) flag = 1;
66 if (flag) cout << x << " ";
67 }
68 cout << v << "\n";
69 return 0;
70}