美文网首页PAT
GPLT L3-011. 直捣黄龙 dijkstra

GPLT L3-011. 直捣黄龙 dijkstra

作者: fruits_ | 来源:发表于2018-03-30 21:36 被阅读5次

    题目链接戳这里
    和紧急救援差不多.用的dijkstra
    用的是map来映射值与名,名与值
    傻了一个小地方: 遇到同样长度的路径时,要考量其它数据再决定是否要改变路径,比如这条路虽长度一样,但其它参数更优.但是对于到某个点的路径数,但凡遇到有同样长度的就可以累加了,不必再考量..
    一样状态数有点多,但是只是繁琐而已.

    #include <bits/stdc++.h>
    #include <iostream>
    using namespace std;
    
    #define mst(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for (int i = (a); i < (b); ++i)
    #define fi first
    #define se second
    const int inf = 0x3f3f3f3f, maxN = 205;
    int N, M;
    map<int, string> mp;
    map<string, int> rmp;
    // 图 访问标记 最短距离 路径记录
    int G[maxN][maxN], vis[maxN], d[maxN], way[maxN];
    // 城内敌数 灭敌数 城镇数 路径条数
    int ds[maxN], mds[maxN], czs[maxN], ts[maxN];
    
    void dijkstra(int s) {
        mst(vis, 0);
        mst(d, inf);
        mst(way, -1);
        mst(mds, 0);
        mst(czs, 0);
        mst(ts, 0);
        d[s] = 0;
        ts[s] = 1;
    
        while (1) {
            int u = -1;
            rep(i, 0, N) if (!vis[i] && (u == -1 || d[i] < d[u])) u = i;
            if (u == -1)
                break;
    
            vis[u] = 1;
            rep(i, 0, N) {
                if (!vis[i] && G[u][i] != inf) {
                    // 距离更短
                    if (d[u] + G[u][i] < d[i]) {
                        d[i] = d[u] + G[u][i];
                        way[i] = u;
                        mds[i] = mds[u] + ds[i];
                        czs[i] = czs[u] + 1;
                        ts[i] = ts[u];
                    } else if (d[u] + G[u][i] == d[i]) {
                        ts[i] += ts[u];
                        if (czs[u] + 1 > czs[i]) {
                            way[i] = u;
                            mds[i] = mds[u] + ds[i];
                            czs[i] = czs[u] + 1;
                        } else if (czs[u] + 1 == czs[i]) {
                            if (mds[u] + ds[i] > mds[i]) {
                                way[i] = u;
                                mds[i] = mds[u] + ds[i];
                            }
                        }
                    }
                }
            }
        }
    }
    
    void print_path(int e) {
        int rway[maxN], cnt = 0;
        int te = e;
        while (te != -1) {
            rway[cnt++] = te;
            te = way[te];
        }
        rep(i, 0, cnt) {
            if (i)
                cout << "->";
            cout << mp[rway[cnt - 1 - i]];
        }
        cout << endl << ts[e] << " " << d[e] << " " << mds[e];
    }
    int main() {
        // freopen("data.in", "r", stdin);
        string a, b;
        cin >> N >> M >> a >> b;
        int c;
        int s = 0, e;
        mp[s] = a;
        rmp[a] = 0;
        ds[s] = 0;
        rep(i, 1, N) {
            cin >> a >> ds[i];
            mp[i] = a;
            rmp[a] = i;
            if (a == b)
                e = i;
        }
        mst(G, inf);
        rep(i, 0, M) {
            cin >> a >> b >> c;
            int na = rmp[a], nb = rmp[b];
            G[na][nb] = G[nb][na] = c;
        }
        dijkstra(s);
        print_path(e);
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:GPLT L3-011. 直捣黄龙 dijkstra

        本文链接:https://www.haomeiwen.com/subject/zbkwcftx.html