Language: C++

#include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
using ll = long long;
#define rep(i, j) for(int i = 0; i < (int)(j); i++)
#define debug(x) cerr << #x << " : " << x << endl

template<class T> ostream&
operator << (ostream &os , const vector<T> &v) { for(const T &t : v) os << "\t" << t; return os << endl; }

const ll INFL = 1LL << 40;

struct Edge {
    int index, from, to;
    ll cost;
    bool multi;
};

using EdgeList = vector<vector<Edge>>;

// ?????£?????????????????°?????? E ???????????????
// O(N + M) N: ????????°, M: ?????°
set<int> enumerate_bridges(const EdgeList &E) {
    int N = E.size();
    vector<int> ord(N, -1), low(N);
    int cnt = 0;
    set<int> bridges;
    function<void(int, int)> dfs = [&] (int now, int pre) {
        ord[now] = cnt++;
        low[now] = ord[now];
        for(const Edge &nxt_e : E[now]) {
            int nxt = nxt_e.to;
            if(ord[nxt] < 0) {
                // not visited
                dfs(nxt, now);
                low[now] = min(low[now], low[nxt]);
            } else if(nxt != pre) {
                // visited
                low[now] = min(low[now], ord[nxt]);
            }
            if(ord[now] < low[nxt]) {
                bridges.insert(nxt_e.index);
            }
        }
    };
    // ??£?????°????????????dfs(0)????????§OK?????????
    dfs(0);
    // rep(i, N) if(ord[i] < 0) dfs(i, -1);
    return bridges;
}


struct State {
    int index;    
    ll cost;
    int from;
    Edge e;
    bool operator > (const State &r) const { return cost > r.cost; }
};

tuple<vector<ll>, vector<vector<Edge>>> dijkstra(const EdgeList &G, int start) {    
    priority_queue<State, vector<State>, greater<State>> que;
    vector<ll> dist(G.size(), INFL);
    vector<vector<Edge>> shortest_graph(G.size());    
    que.push(State{start, 0, -1});
    dist[start] = 0;
    while(not que.empty()) {
        State now = que.top(); que.pop();
        if(dist[now.index] < now.cost) continue;
        if(now.from >= 0) {
            shortest_graph[now.from].push_back(now.e);
            shortest_graph[now.index].push_back(Edge{now.e.index, now.e.from, now.e.to, now.e.cost});
        }
        for(Edge e : G[now.index]){
            if(dist[e.to] >= now.cost + e.cost){
                State nxt = State{ e.to, now.cost + e.cost, now.index, e};
                dist[e.to] = nxt.cost;
                que.push(nxt);
            }
        }
    }
    return make_tuple(dist, shortest_graph);
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int N, M; cin >> N >> M;
    EdgeList E(N), rE(N);
    vector<Edge> edges;    
    rep(i, M) {
        int a, b, c; cin >> a >> b >> c;
        edges.push_back(Edge{i, a - 1, b - 1, c, false});
    }
    sort(begin(edges), end(edges), [] (const Edge &a, const Edge &b) {
            return make_tuple(a.from, a.to, a.cost) < make_tuple(b.from, b.to, b.cost);
        });
    rep(i, M) {
        auto &e = edges[i]; // mut
        int index = e.index;
        int a = e.from;
        int b = e.to;
        int c = e.cost;
        if(i > 0) {
            auto &pe = edges[i - 1]; // mut
            if(pe.from == a and pe.to == b) {
                e.multi = true;
                if(pe.cost == e.cost) edges[i - 1].multi = true;
                continue;
            }
        }
        E[a].push_back(Edge{index, a, b, c});
        rE[b].push_back(Edge{index, b, a, c});
    }

    vector<ll> dist, r_dist;
    vector<vector<Edge>> shortest_graph, r_shortest_graph;
    tie(dist, shortest_graph) = dijkstra(E, 0);
    tie(r_dist, r_shortest_graph) = dijkstra(rE, 1);

    assert(dist[1] < INFL);
    assert(dist[1] == r_dist[0]);

    auto bridges = enumerate_bridges(shortest_graph);
    
    sort(begin(edges), end(edges), [] (const Edge &a, const Edge &b) {
            return a.index < b.index;
        });
    rep(i, M) {
        const Edge &e = edges[i];
        if(dist[e.to] + e.cost + r_dist[e.from] < dist[1]) {
            cout << "HAPPY" << endl;
        } else if(dist[e.to] + e.cost + r_dist[e.from] == dist[1]) {
            cout << "SOSO" << endl;
        } else if(dist[e.from] + e.cost + r_dist[e.to] == dist[1] and bridges.count(i) and not e.multi) {
            cout << "SAD" << endl;
        } else {
            cout << "SOSO" << endl;
        }
    }
    return 0;
}

Compiler output:
a.cc: In function 'std::set<int> enumerate_bridges(const EdgeList&)':
a.cc:48:8: error: no match for call to '(std::function<void(int, int)>) (int)'
   48 |     dfs(0);
      |     ~~~^~~
In file included from /usr/include/c++/14/functional:59,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:53,
                 from a.cc:1:
/usr/include/c++/14/bits/std_function.h:587:7: note: candidate: '_Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {int, int}]'
  587 |       operator()(_ArgTypes... __args) const
      |       ^~~~~~~~
/usr/include/c++/14/bits/std_function.h:587:7: note:   candidate expects 2 arguments, 1 provided