题意:给好多个城市的机票价格,旅行过程中可以把某张机票价格减半。求城市A到城市B的最小费用。
思路:求出A到每个城市的价格和B到每个城市的价格,遍历每条边求出最小价格。写完spfa就各种wa,找了一下午。开始我以为是无向图,就建了一个图。算B到每个城市价格的时候就错了,应该建反向图的。
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <deque>
#include <set>
#include <string>
using namespace std;
#define For(i,a) for(i=0;i<a;i++)
#define Foru(i,a,b) for(i=a;i<=b;i++)
#define Ford(i,a,b) for(i=a;i>=b;i--)
#define clr(ar,vel) memset(ar,vel,sizeof(ar))
#define PB push_back
#define maxint 0x7fffffff
const long long maxll =1LL<<60;
typedef long long ll;
const int maxn = 100010;
struct edge{int to, dis;};
vector<edge> G[maxn], GB[maxn];
map<string, int> ma;
bool vis[maxn];
ll s_dis[maxn], t_dis[maxn];
int n, m, cnt;
int getNum(string s){
if( !ma.count(s)) return ma[s] = cnt++;
else return ma[s];
}
void spfa(int s, ll *dis, vector<edge> *G){
memset(vis, 0, sizeof(vis));
fill(dis, dis+n, maxll);
deque<int> q;
q.push_back(s);
vis[s] = 1;
dis[s] = 0;
while(q.size()){
int fn = q.front(); q.pop_front();
vis[fn] = 0;
for(int i = 0; i < G[fn].size(); i ++){
int to = G[fn][i].to;
int vel = G[fn][i].dis;
if( dis[to] > dis[fn] + vel) {
dis[to] = dis[fn] + vel;
if( !vis[to]) {
if( q.size() && dis[to] < dis[q.front()]) q.push_front(to);
else q.push_back(to);
vis[to] = 1;
}
}
}
}
}
int main(){
ios::sync_with_stdio(false);
string f, t;
int dis, from, to;
while(cin >> n >> m){
// cout << maxint << ' ' << maxll << endl;
for(int i = 0; i < n; i ++) {
G[i].clear();
GB[i].clear();
}
ma.clear();
cnt = 0;
while(m--){
cin >> f >> t >> dis;
from = getNum(f); to = getNum(t);
G[from].push_back((edge){to, dis});
GB[to].push_back((edge){from, dis});
}
cin >> f >> t;
from = getNum(f); to = getNum(t);
spfa(from, s_dis, G);
spfa(to, t_dis, GB);
ll ans = maxll;
for(int i = 0; i < n; i ++){
for(int j = 0; j < G[i].size(); j ++){
int t = G[i][j].to;
dis = G[i][j].dis;
if( s_dis[i] < maxll && t_dis[t] < maxll ) ans = min(ans, s_dis[i] + t_dis[t] + dis/2);
}
}
if( ans >= maxll ) ans = -1;
cout << ans << endl;
}
return 0;
}