最短路問題
題意:
給定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;
}