PAY 甲級 1087 All Roads Lead to Rome (30 分) dij最短路

最短路問題

題意:

給定n個點m條邊的無向圖,找一條最短路徑,距離一樣的話找路徑總happy值(每個點有一個happy值)最大的,如果happy一樣大的話,找平均happy值最大的(也就是經過的點儘量少的)

思路:

使用n²  的 dijstra算法,d[i][] 數組的第一維表示當前點i,第二維分別表示(帶初始化):

        d[i][0] = INF; // dis          到當前點的最短距離
        d[i][1] = 0; // happy        到i點最短路徑的總happy值
        d[i][2] = -1; // fa              到i點最短路徑上的前驅結點
        d[i][3] = 1; // cnt             到i點爲最短路徑時經過的點的個數
        d[i][4] = 0; // num           到i點最短路徑的條數

根據要求在鬆弛操作的時候,更新上述的值

#include<bits/stdc++.h>
#include<cstring>
#define FI first
#define SE second

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 200 + 7;
const int INF = 0x7f7f7f7f;

int n, m;
string sta;
string na[maxn];
int h[maxn];
map<string, int> mp;
vector<P> vec[maxn];
int d[maxn][5];
bool vis[maxn];

void print(int en) {
    stack<int> ans;
    while(en != -1) {
        ans.push(en);
        en = d[en][2];
    }
    while(!ans.empty()) {
        int t = ans.top(); ans.pop();
        cout << na[t];
        if(!ans.empty()) cout << "->";
    }
}
void solve() {
    for(int i = 1; i <= n; ++i) {
        d[i][0] = INF; // dis
        d[i][1] = 0; // happy
        d[i][2] = -1; // fa
        d[i][3] = 1; // cnt
        d[i][4] = 0; // num
    }
    d[1][0] = 0;
    d[1][4] = 1;
    for(auto i : vec[1]) {
        d[i.FI][0] = i.SE;
    }
    while(1) {
        int t = -1;
        for(int i =1; i <= n; ++i) {
            if(!vis[i] && (t == -1 || d[i][0] < d[t][0])) t = i;
        }
        if(t == -1) break;
        vis[t] = 1;
        for(auto i : vec[t]) {
            if(d[i.FI][0] > d[t][0] + i.SE) {
                d[i.FI][0] = d[t][0] + i.SE;
                d[i.FI][1] = d[t][1] + h[i.FI];
                d[i.FI][2] = t;
                d[i.FI][3] = d[t][3] + 1;
                d[i.FI][4] = d[t][4];
            }
            else if(d[i.FI][0] == d[t][0] + i.SE) {
                d[i.FI][4] += d[t][4];
                if(d[i.FI][1] < d[t][1] + h[i.FI]) {
                    d[i.FI][1] = d[t][1] + h[i.FI];
                    d[i.FI][2] = t;
                    d[i.FI][3] = d[t][3] + 1;
                }
                else if(d[i.FI][1] == d[t][1] + h[i.FI]) {
                    if(d[i.FI][3] > d[t][3] + 1) {
                        d[i.FI][2] = t;
                        d[i.FI][3] = d[t][3] + 1;
                    }
                }
            }
        }
    }
    int en = mp["ROM"];
    //cout << d[en][0] << " + " << d[en][1] << " + " << d[en][2] << " + " << d[en][3] << " + " << d[en][4] <<  endl;
    cout << d[en][4] << " " << d[en][0] << " " << d[en][1] << " " << floor(d[en][1]/(d[en][3]-1)) << endl;
    print(en);
}
int main() {
    cin >> n >> m >> sta;
    mp[sta] = 1;
    na[1] = sta;
    for(int i = 2; i <= n; ++i) {
        cin >> na[i] >> h[i];
        mp[na[i]] = i;
    }
    string s, t;
    int s_, t_, v;
    for(int i = 1; i <= m; ++i) {
        cin >> s >> t >> v;
        s_ = mp[s];
        t_ = mp[t];
        vec[s_].push_back(P(t_, v));
        vec[t_].push_back(P(s_, v));
    }
    solve();
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章