这个题真的是做的我很难受,就是从开始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");
}
}
}