​点击打开链接​

这道题一开始没有思路 看了一下别人的博客 代码自己实现

还是反向存图

如果直接改变一条边的花费 很可能会使之前求得的两点之前的最短路失去意义

方法就是 遍历每条边 起点到这条边左顶点的花费 这条边打折后的花费 还有终点到这条边右顶点的花费(反向图) 三者相加

这样两条最短路一定是正确的 不受当前遍历到的这条边的花费打折的影响

遍历结束 最小值即为所求

 

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <string>
#define N 1e17
using namespace std;

struct node1
{
int v;
long long w;
};

struct node2
{
friend bool operator < (node2 n1,node2 n2)
{
return n1.s>n2.s;
}
int id;
long long s;
};

vector <struct node1> edge1[500010];
vector <struct node1> edge2[500010];
map <string,int> mp;

long long dis1[100010],dis2[100010];
int book[100010];
int n,m,num,s,f;

int fun(string s)
{
if(mp.find(s)==mp.end())
{
mp[s]=++num;
}
return mp[s];
}

void calculate1();
void calculate2();

int main()
{
string s1,s2;
struct node1 t;
long long c,ans,sum,tem;
int i,j,a,b,flagu,flagv;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
{
edge1[i].clear();
edge2[i].clear();
}
mp.clear();
num=0;
for(i=1;i<=m;i++)
{
cin>>s1>>s2>>c;
a=fun(s1),b=fun(s2);
t.v=b,t.w=c;
edge1[a].push_back(t);
t.v=a,t.w=c;
edge2[b].push_back(t);
}
cin>>s1>>s2;
s=fun(s1),f=fun(s2);
calculate1();
calculate2();
ans=N;
for(i=1;i<=num;i++)
{
for(j=0;j<edge1[i].size();j++)
{
t=edge1[i][j];
tem=t.w/2;
sum=dis1[i]+tem+dis2[t.v];
if(ans>sum) ans=sum;
}
}
if(ans<N)
{
printf("%lld\n",ans);
}
else
{
printf("-1\n");
}
}
return 0;
}

void calculate1()
{
priority_queue <struct node2> que;
struct node1 t;
struct node2 cur,tem;
long long minn;
int i,j,p;
for(i=1;i<=num;i++)
{
dis1[i]=N;
book[i]=0;
}
dis1[s]=0;
tem.id=s;
tem.s=0;
que.push(tem);
for(i=0;i<edge1[s].size();i++)
{
t=edge1[s][i];
dis1[t.v]=t.w;
tem.id=t.v;
tem.s=dis1[t.v];
que.push(tem);
}
while(!que.empty())
{
cur=que.top();
que.pop();
p=cur.id;
if(book[p]==1) continue;
book[p]=1;
for(i=0;i<edge1[p].size();i++)
{
t=edge1[p][i];
if(dis1[t.v]>dis1[p]+t.w)
{
dis1[t.v]=dis1[p]+t.w;
tem.id=t.v;
tem.s=dis1[t.v];
que.push(tem);
}
}
}
return;
}

void calculate2()
{
priority_queue <struct node2> que;
struct node1 t;
struct node2 cur,tem;
long long minn;
int i,j,p;
for(i=1;i<=num;i++)
{
dis2[i]=N;
book[i]=0;
}
dis2[f]=0;
tem.id=f;
tem.s=0;
que.push(tem);
for(i=0;i<edge2[f].size();i++)
{
t=edge2[f][i];
dis2[t.v]=t.w;
tem.id=t.v;
tem.s=dis2[t.v];
que.push(tem);
}
while(!que.empty())
{
cur=que.top();
que.pop();
p=cur.id;
if(book[p]==1) continue;
book[p]=1;
for(i=0;i<edge2[p].size();i++)
{
t=edge2[p][i];
if(dis2[t.v]>dis2[p]+t.w)
{
dis2[t.v]=dis2[p]+t.w;
tem.id=t.v;
tem.s=dis2[t.v];
que.push(tem);
}
}
}
return;
}