#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
const int N = 1e5 + 5;
const int MOD = 1e9 + 9277;
void add(int& a, int b) {
a += b;
if (a >= MOD) a -= MOD;
}
struct Edge {
int u, v, w;
};
int n, m, s, t;
vector<ii> adj[N], radj[N];
vector<Edge> edges;
struct Node {
int u; ll d;
bool operator<(const Node& other) const {
return d > other.d;
}
};
ll dist_s[N]; // dist_s[u] = Đường đi ngắn nhất từ s đến u
ll dist_t[N]; // dist_t[u] = Đường đi ngắn nhất từ u đến t
int cnt_s[N]; // cnt_s[u] = Số đường đi ngắn nhất từ s đến u
int cnt_t[N]; // cnt_t[u] = Số đường đi ngắn nhất từ u đến t
void dijkstra(int s, vector<ii> adj[], ll dist[], int cnt[]) {
for (int u = 1; u <= n; u++) {
dist[u] = LINF;
cnt[u] = 0;
}
priority_queue<Node> pq;
dist[s] = 0;
cnt[s] = 1;
pq.push({s, dist[s]});
while (!pq.empty()) {
Node front = pq.top(); pq.pop();
int u = front.u; ll d = front.d;
if (d > dist[u]) continue;
for (ii v : adj[u]) {
if (dist[u] + v.second < dist[v.first]) {
dist[v.first] = dist[u] + v.second;
cnt[v.first] = cnt[u];
pq.push({v.first, dist[v.first]});
}
else if (dist[u] + v.second == dist[v.first]) {
add(cnt[v.first], cnt[u]);
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> s >> t;
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back({v, w});
radj[v].push_back({u, w});
edges.push_back({u, v, w});
}
dijkstra(s, adj, dist_s, cnt_s);
dijkstra(t, radj, dist_t, cnt_t);
for (Edge e : edges) {
if (dist_s[e.u] == LINF || dist_t[e.v] == LINF) {
cout << "NO" << '\n';
continue;
}
// Điều kiện để cạnh e nằm trên MỌI đường đi ngắn nhất từ s đến t
if (dist_s[e.u] + e.w + dist_t[e.v] == dist_s[t] && 1ll * cnt_s[e.u] * cnt_t[e.v] % MOD == cnt_s[t]) {
cout << "YES" << '\n';
}
else {
// Trọng số new_w để e nằm trên MỌI đường đi ngắn nhất từ s đến t
int new_w = dist_s[t] - dist_s[e.u] - dist_t[e.v] - 1;
int cost = e.w - new_w;
if (new_w > 0) {
cout << "CAN " << cost << '\n';
}
else {
cout << "NO" << '\n';
}
}
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKY29uc3QgaW50IE4gPSAxZTUgKyA1OyAKY29uc3QgaW50IE1PRCA9IDFlOSArIDkyNzc7IAoKdm9pZCBhZGQoaW50JiBhLCBpbnQgYikgewoJYSArPSBiOyAKCWlmIChhID49IE1PRCkgYSAtPSBNT0Q7IAp9CgpzdHJ1Y3QgRWRnZSB7CglpbnQgdSwgdiwgdzsgCn07IAoKaW50IG4sIG0sIHMsIHQ7IAp2ZWN0b3I8aWk+IGFkaltOXSwgcmFkaltOXTsgCnZlY3RvcjxFZGdlPiBlZGdlczsgIAoKc3RydWN0IE5vZGUgewoJaW50IHU7IGxsIGQ7IAoJYm9vbCBvcGVyYXRvcjwoY29uc3QgTm9kZSYgb3RoZXIpIGNvbnN0IHsKCQlyZXR1cm4gZCA+IG90aGVyLmQ7IAoJfQp9OyAKCmxsIGRpc3Rfc1tOXTsgLy8gZGlzdF9zW3VdID0gxJDGsOG7nW5nIMSRaSBuZ+G6r24gbmjhuqV0IHThu6sgcyDEkeG6v24gdQpsbCBkaXN0X3RbTl07IC8vIGRpc3RfdFt1XSA9IMSQxrDhu51uZyDEkWkgbmfhuq9uIG5o4bqldCB04burIHUgxJHhur9uIHQKaW50IGNudF9zW05dOyAvLyBjbnRfc1t1XSA9IFPhu5EgxJHGsOG7nW5nIMSRaSBuZ+G6r24gbmjhuqV0IHThu6sgcyDEkeG6v24gdQppbnQgY250X3RbTl07IC8vIGNudF90W3VdID0gU+G7kSDEkcaw4budbmcgxJFpIG5n4bqvbiBuaOG6pXQgdOG7qyB1IMSR4bq/biB0Cgp2b2lkIGRpamtzdHJhKGludCBzLCB2ZWN0b3I8aWk+IGFkaltdLCBsbCBkaXN0W10sIGludCBjbnRbXSkgewoJZm9yIChpbnQgdSA9IDE7IHUgPD0gbjsgdSsrKSB7CgkJZGlzdFt1XSA9IExJTkY7ICAKCQljbnRbdV0gPSAwOyAKCX0KCglwcmlvcml0eV9xdWV1ZTxOb2RlPiBwcTsgCglkaXN0W3NdID0gMDsgCgljbnRbc10gPSAxOyAKCXBxLnB1c2goe3MsIGRpc3Rbc119KTsgCgoJd2hpbGUgKCFwcS5lbXB0eSgpKSB7CgkJTm9kZSBmcm9udCA9IHBxLnRvcCgpOyBwcS5wb3AoKTsgIAoJCWludCB1ID0gZnJvbnQudTsgbGwgZCA9IGZyb250LmQ7ICAKCgkJaWYgKGQgPiBkaXN0W3VdKSBjb250aW51ZTsgCgoJCWZvciAoaWkgdiA6IGFkalt1XSkgewoJCQlpZiAoZGlzdFt1XSArIHYuc2Vjb25kIDwgZGlzdFt2LmZpcnN0XSkgewoJCQkJZGlzdFt2LmZpcnN0XSA9IGRpc3RbdV0gKyB2LnNlY29uZDsgCgkJCQljbnRbdi5maXJzdF0gPSBjbnRbdV07IAoJCQkJcHEucHVzaCh7di5maXJzdCwgZGlzdFt2LmZpcnN0XX0pOyAKCQkJfQoJCQllbHNlIGlmIChkaXN0W3VdICsgdi5zZWNvbmQgPT0gZGlzdFt2LmZpcnN0XSkgewoJCQkJYWRkKGNudFt2LmZpcnN0XSwgY250W3VdKTsgCgkJCX0KCQl9Cgl9Cn0KCmludCBtYWluKCkgewoJaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyAKCWNpbi50aWUobnVsbHB0cik7IAkKCWNpbiA+PiBuID4+IG0gPj4gcyA+PiB0OyAKCglmb3IgKGludCBpID0gMDsgaSA8IG07IGkrKykgewoJCWludCB1LCB2LCB3OyAKCQljaW4gPj4gdSA+PiB2ID4+IHc7IAoJCWFkalt1XS5wdXNoX2JhY2soe3YsIHd9KTsgCgkJcmFkalt2XS5wdXNoX2JhY2soe3UsIHd9KTsgCgkJZWRnZXMucHVzaF9iYWNrKHt1LCB2LCB3fSk7IAoJfQoKCWRpamtzdHJhKHMsIGFkaiwgZGlzdF9zLCBjbnRfcyk7CglkaWprc3RyYSh0LCByYWRqLCBkaXN0X3QsIGNudF90KTsgIAoKCWZvciAoRWRnZSBlIDogZWRnZXMpIHsKCQlpZiAoZGlzdF9zW2UudV0gPT0gTElORiB8fCBkaXN0X3RbZS52XSA9PSBMSU5GKSB7CgkJCWNvdXQgPDwgIk5PIiA8PCAnXG4nOyAKCQkJY29udGludWU7IAoJCX0KCgkJLy8gxJBp4buBdSBraeG7h24gxJHhu4MgY+G6oW5oIGUgbuG6sW0gdHLDqm4gTeG7jEkgxJHGsOG7nW5nIMSRaSBuZ+G6r24gbmjhuqV0IHThu6sgcyDEkeG6v24gdAoJCWlmIChkaXN0X3NbZS51XSArIGUudyArIGRpc3RfdFtlLnZdID09IGRpc3Rfc1t0XSAmJiAxbGwgKiBjbnRfc1tlLnVdICogY250X3RbZS52XSAlIE1PRCA9PSBjbnRfc1t0XSkgewoJCQljb3V0IDw8ICJZRVMiIDw8ICdcbic7IAoJCX0KCQllbHNlIHsKCQkJLy8gVHLhu41uZyBz4buRIG5ld193IMSR4buDIGUgbuG6sW0gdHLDqm4gTeG7jEkgxJHGsOG7nW5nIMSRaSBuZ+G6r24gbmjhuqV0IHThu6sgcyDEkeG6v24gdAoJCQlpbnQgbmV3X3cgPSBkaXN0X3NbdF0gLSBkaXN0X3NbZS51XSAtIGRpc3RfdFtlLnZdIC0gMTsgIAoJCQlpbnQgY29zdCA9IGUudyAtIG5ld193OyAgIAoKCQkJaWYgKG5ld193ID4gMCkgewoJCQkJY291dCA8PCAiQ0FOICIgPDwgY29zdCA8PCAnXG4nOyAKCQkJfQoJCQllbHNlIHsKCQkJCWNvdXQgPDwgIk5PIiA8PCAnXG4nOyAKCQkJfQoJCX0KCX0KfQ==