這個題真的是做的我很難受,就是從開始sa的點搜一次,找到它到每個點的最短路dis1[I],再從終點sb搜一次,找到它到每個點的最短路dis[I],我建立了兩個圖,因爲是單向的。搜完兩次之後,再枚舉所有的路,假設其中一個是從a到b,權值爲w,則
dis1[a]+dis2[b]+w/2就是始點sa到終點sb,把優惠券用到a到b這條路上的結果ans。循環m次,就能得到一個最小值。
下面是AC代碼:
爲啥得分好幾次才能粘貼完?無語
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define inf 1e17
const int N=100010;
int n,m;
int book[N];
long long dis1[N],dis2[N];
struct node
{
int to;
long long w;
bool operator <(const node &s)const
{
return w>s.w;
}
};
char sta[15],stb[15],b[15],c[15];
map<string,int>station;
vector<node>v1[N];
vector<node>v2[N];
void dij1(int ss)
{
priority_queue<node>q;
while(!q.empty()){q.pop();}
for(int i=0;i<=n;i++){
dis1[i]=inf;
}
dis1[ss]=0;
struct node now,next;
now.to=ss;
now.w=0;
q.push(now);
while(!q.empty())
{
now=q.top();
q.pop();
//cout<<ss<<" "<<v1[now.to].size()<<endl;
for(int i=0;i<v1[now.to].size();i++)
{
next=v1[now.to][i];
if(dis1[next.to]>dis1[now.to]+next.w)
{
dis1[next.to]=dis1[now.to]+next.w;
//cout<<dis1[next.to]<<endl;
q.push(next);
}
}
}
}
void dij2(int ss)
{
priority_queue<node>q;
while(!q.empty()){q.pop();}
for(int i=0;i<=n;i++){
dis2[i]=inf;
}
dis2[ss]=0;
struct node now,next;
now.to=ss;
now.w=0;
q.push(now);
while(!q.empty())
{
now=q.top();
q.pop();
for(int i=0;i<v2[now.to].size();i++)
{
next=v2[now.to][i];
if(dis2[next.to]>dis2[now.to]+next.w)
{
dis2[next.to]=dis2[now.to]+next.w;
q.push(next);
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int nn=0,sa=0,sb=0;
long long w;
station.clear();
for(int i=0;i<=N;i++){
v1[i].clear();
v2[i].clear();
}
for(int i=1;i<=m;i++)
{
scanf("%s%s%lld",b,c,&w);
if(!station[b]){
station[b]=++nn;
}
if(!station[c]){
station[c]=++nn;
}
v1[station[b]].push_back(node{station[c],w});
v2[station[c]].push_back(node{station[b],w});
}
scanf("%s%s",sta,stb);
if(!station[sta]){
station[sta]=++nn;
//sa=station[sta];
}
if(!station[stb]){
station[stb]=++nn;
//sb=station[stb];
}
//cout<<station[sta]<<" "<<station[stb]<<endl;
dij1(station[sta]);
dij2(station[stb]);
//cout<<dis1[sb]<<" "<<dis2[sa]<<endl;
long long ans=inf,dd;
struct node noww;
for(int i=1;i<=nn;i++)
{
for(int j=0;j<v1[i].size();j++){
noww=v1[i][j];
if(ans>dis1[i]+dis2[noww.to]+noww.w/2)
{
ans=dis1[i]+dis2[noww.to]+noww.w/2;
}
}
}
if(ans<inf){
printf("%lld\n",ans);
}
else {
printf("-1\n");
}
}
}