原題:
https://cses.fi/problemset/task/1672
題意:
給定 n 個點、m 條有向邊、q 個查詢。每個查詢問 a→b 的最短距離;若不可達輸出 -1。
解題思路:
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, m, q;
    cin >> n >> m >> q;
    const long long INF = (long long)4e18;
    vector<vector<long long>> dist(n+1, vector<long long>(n+1, INF));
    for (int i = 1; i <= n; ++i) dist[i][i] = 0;
    for (int i = 0; i < m; ++i) {
        int a, b; long long w;
        cin >> a >> b >> w;
        dist[a][b] = min(dist[a][b], w); // 處理多重邊
    }
    for (int k = 1; k <= n; ++k) {
        for (int i = 1; i <= n; ++i) if (dist[i][k] < INF) {
            for (int j = 1; j <= n; ++j) if (dist[k][j] < INF) {
                long long nd = dist[i][k] + dist[k][j];
                if (nd < dist[i][j]) dist[i][j] = nd;
            }
        }
    }
    while (q--) {
        int a, b; cin >> a >> b;
        long long ans = dist[a][b];
        cout << (ans >= INF/2 ? -1 : ans) << "\n";
    }
    return 0;
}
原題:
https://cses.fi/problemset/task/1678
題意:
給一張有向圖,若存在有向環,輸出該環的節點序列;否則輸出 IMPOSSIBLE。
解題思路:
#include <bits/stdc++.h>
using namespace std;
int main(){
    cin >> n >> m;
    vector<vector<int>> g(n+1);
    for(int i=0;i<m;i++){
        int u,v; cin >> u >> v;
        g[u].push_back(v);
    }
    vector<int> color(n+1,0), parent(n+1,-1);
    int cyc_u=-1, cyc_v=-1;
    function<bool(int)> dfs = [&](int u){
        color[u]=1;
        for(int v: g[u]){
            if(color[v]==0){
                parent[v]=u;
                if(dfs(v)) return true;
            }else if(color[v]==1){
                cyc_u=u; cyc_v=v; // 發現回邊 u->v
                return true;
            }
        }
        color[u]=2;
        return false;
    };
    for(int i=1;i<=n;i++){
        if(color[i]==0 && dfs(i)){
            // 重建環 v ... u -> v
            vector<int> cyc; cyc.push_back(cyc_v);
            for(int x=cyc_u; x!=cyc_v; x=parent[x]) cyc.push_back(x);
            cyc.push_back(cyc_v);
            reverse(cyc.begin(), cyc.end());
            cout << cyc.size() << "\n";
            for(size_t k=0;k<cyc.size();k++)
                cout << cyc[k] << (k+1==cyc.size()?'\n':' ');
            return 0;
        }
    }
    cout << "IMPOSSIBLE\n";
    return 0;
}
原題:
https://leetcode.com/problems/cheapest-flights-within-k-stops/description/
題意:
城市 n、航線 flights[u,v,w],從 src 飛到 dst,最多 K 次中轉(即最多 K+1 段航班)。求最小成本,不能到達回傳 -1。
解題思路:
class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        const int INF = 1e9;
        vector<int> dist(n, INF);
        dist[src] = 0;
        // 允許最多 K 次中轉 → 最多 K+1 段邊
        for (int t = 0; t <= K; ++t) {
            vector<int> nd = dist; // 只用上一輪結果
            for (auto &e: flights) {
                int u = e[0], v = e[1], w = e[2];
                if (dist[u] == INF) continue;
                nd[v] = min(nd[v], dist[u] + w);
            }
            dist.swap(nd);
        }
        return dist[dst] >= INF/2 ? -1 : dist[dst];
    }
};
題意:
給定無向加權圖與門檻 distanceThreshold。對每個城市 i,計算所有 dist[i][j] <= threshold 的城市數量(不含自己),回傳 鄰居數最少 的城市;若有多個,回傳 索引較大 的那個。
解題思路:
class Solution {
public:
    int findTheCity(int n, vector<vector<int>>& edges, int threshold) {
        const int INF = 1e9;
        vector<vector<int>> dist(n, vector<int>(n, INF));
        for (int i = 0; i < n; ++i) dist[i][i] = 0;
        for (auto &e: edges) {
            int u=e[0], v=e[1], w=e[2];
            dist[u][v] = min(dist[u][v], w);
            dist[v][u] = min(dist[v][u], w);
        }
        for (int k = 0; k < n; ++k)
            for (int i = 0; i < n; ++i) if (dist[i][k] < INF)
                for (int j = 0; j < n; ++j) if (dist[k][j] < INF)
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
        int bestCity = -1, bestCnt = INT_MAX;
        for (int i = 0; i < n; ++i) {
            int cnt = 0;
            for (int j = 0; j < n; ++j)
                if (i != j && dist[i][j] <= threshold) cnt++;
            // 鄰居數更少,或平手取索引較大
            if (cnt < bestCnt || (cnt == bestCnt && i > bestCity)) {
                bestCnt = cnt; bestCity = i;
            }
        }
        return bestCity;
    }
};