图论10&11

94. 城市间货物运输 I

SPFA

#include <iostream>
#include <vector>
#include <list>
#include <climits>
#include <queue>

using namespace std;

struct Node {
    int to, value;
    Node(int mto, int mvalue): to(mto), value(mvalue) {}
};

int main() {
    int n, m;
    cin >> n >> m;
    int s, t, v;
    vector<list<Node>> grid(n + 1);
    for (int i = 0; i < m; i++) {
        cin >> s >> t >> v;
        grid[s].push_back(Node(t, v));
    }
    int start = 1;
    int end = n;
    
    vector<int> minDist(n + 1, INT_MAX);
    minDist[start] = 0;

    queue<int> que;
    que.push(start);
    vector<bool> isInQueue(n + 1, false); // 加入优化,已经在队里里的元素不用重复添加

    while(!que.empty()) {
        int cur = que.front(); que.pop();
 
        isInQueue[cur] = false;
        for (Node node: grid[cur]) {
            int from = cur;
            int to = node.to;
            int value = node.value;
            if (minDist[to] > minDist[from] + value) {
                minDist[to] = minDist[from] + value;
                if (!isInQueue[to]) {
                    que.push(to);
                    isInQueue[to] = true;
                }
            }
        }
    }



    if (minDist[n] == INT_MAX) cout << "unconnected";
    else cout << minDist[n];

    return 0;
}

95. 城市间货物运输 II

bellman_ford之判断负权回路

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct Edge {
    int to;
    int val;
    Edge(int mto, int mval): to(mto), val(mval) {}
};

int main() {
    int n, m;
    cin >> n >> m;
    int s, t, v;
    vector<vector<Edge>> egdes(n + 1);
    for (int i = 0; i < m; i++) {
        cin >> s >> t >> v;
        egdes[s].push_back(Edge(t, v));
    }
    vector<int> minDist(n + 1, 10001);
    vector<int> count(n + 1, 0);
    vector<bool> inQueue(n + 1, false);
    queue<int> que;
    int start = 1, end = n;
    minDist[start] = 0;
    inQueue[start] = true;
    count[start]++;
    que.push(start);
    int flag = false;
    while(!que.empty()) {
        int cur = que.front(); que.pop();
        inQueue[cur] = false;
        vector<Edge> cur_edge = egdes[cur];
        for (int i = 0; i < cur_edge.size(); i++) {
            int from = cur;
            int to = cur_edge[i].to;
            int val = cur_edge[i].val;
            if (minDist[to] > minDist[from] + val) {
                minDist[to] = minDist[from] + val;
                
                count[to]++;
                
                if (count[to] > n) {
                    flag = true;
                    while (!que.empty()) {
                        que.pop();
                    }
                    break;
                }
                if (!inQueue[to])
                {
                    que.push(to);
                    inQueue[to] = true;
                }
                    
            }
        }
        
        
    }
    if (flag == true) cout << "circle";
    else if (minDist[end] == 10001) cout << "unconnected";
    else cout << minDist[end];



    return 0;
}

96. 城市间货物运输 III

bellman_ford之单源有限最短路

#include <iostream>
#include <vector>
#include <climits>

using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    int s, t, v;
    vector<vector<int>> edges;
    for (int i = 0; i < m; i++) {
        cin >> s >> t >> v;
        edges.push_back({s, t, v});
    }
    int src , dst , k;
    cin >> src >> dst >> k;
    vector<int> minDist(n + 1, 10001);
    minDist[src] = 0;
    vector<int> copy_minDist(n + 1, 10001);
    for (int i = 1; i <= k + 1; i++) {
        copy_minDist = minDist; 
        for (int j = 0; j < edges.size(); j++) {
            int from = edges[j][0];
            int to = edges[j][1];
            int val = edges[j][2];
            if (copy_minDist[from] != 10001 && minDist[to] > copy_minDist[from] + val) {
                minDist[to] = copy_minDist[from] + val;
            }
        }
        
    }
    if (minDist[dst] == 10001) cout << "unreachable";
    else cout << minDist[dst];

    return 0;
}

97. 小明逛公园

Floyd 算法

#include <iostream>
#include <vector>
#include <climits>

using namespace std;

int main() {

    int n, m;
    cin >> n >> m;
    vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 10005)));
    int u, v, w;
    while(m--) {
        cin >> u >> v >> w;
        dp[u][v][0] = w;
        dp[v][u][0] = w;
    }

    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j][k] = min(dp[i][k][k - 1]+ dp[k][j][k - 1], dp[i][j][k - 1]);
            }
        }
    }

    int q;
    cin >> q;
    int start, end;
    while(q--) {
        cin >> start >> end;
        if (dp[start][end][n] == 10005)
            cout << "-1" << '\n';
        else
            cout << dp[start][end][n] << '\n';
    }

    return 0;
}

127. 骑士的攻击

A star算法

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;
int moves[1001][1001];
int b1, b2;
int n;
int dirt[8][2] = {-2, 1, 2, -1, 1, -2, -1, 2, -2, -1, 2, 1, -1, -2, 1, 2};


struct Knight {
    int x, y, g, h, f;
    bool operator < (const Knight & k) const{  // 重载运算符, 从小到大排序
     return k.f < f;
    }
};

priority_queue<Knight> que;

int Edist(const Knight &k) {
    return (k.y - b2) * (k.y - b2) + (k.x - b1) * (k.x - b1);
}


void Astar(const Knight &k) {
    Knight cur, next;
    que.push(k);
    while(!que.empty()) {
        cur = que.top(); que.pop();
        if(cur.x == b1 && cur.y == b2)
		    break;
        for (int i = 0; i < 8; i++) {
            next.x = cur.x + dirt[i][0];
            next.y = cur.y + dirt[i][1];
           
            if (next.x < 1 || next.x > 1000 || next.y < 1 || next.y > 1000)  continue;
            if (!moves[next.x][next.y]) {
                moves[next.x][next.y] = moves[cur.x][cur.y] + 1;
                next.g = cur.g + 5;
                next.h = Edist(next);
                next.f = next.g + next.h;
                que.push(next);
            }
        }
    }
}

int main() {
    cin >> n;
    while(n--) {
        int a1, a2;
        cin >> a1 >> a2 >> b1 >> b2;
        memset(moves,0,sizeof(moves));
        Knight k;
        k.x = a1;
        k.y = a2;
        k.g = 0;
        k.h = Edist(k);
        k.f = k.g + k.h;
        Astar(k);
        while(!que.empty()) que.pop(); 
        cout << moves[b1][b2] << '\n';
    }

    return 0;
}
posted @ 2025-08-22 19:17  skyler886  阅读(4)  评论(0)    收藏  举报