题目链接:
https://www.luogu.org/problem/P1951
类似题目:
https://www.luogu.org/problem/P1462
思路:
1:关于具体的解题思路,已经在上一篇博客中讲的很详细了,这里不再陈述
https://blog.csdn.net/aiwo1376301646/article/details/100609968
2:这里指出这道题目的数据较上一道类似题目-----P1462 通往奥格瑞玛的道路https://www.luogu.org/problem/P1462-----的加强之处:求最多一次交费的最小值时,最多一次交费ans要在ans和起点point[s]中取较大值,即
printf("%d\n",max(ans,point[s]));
3:关于spfa让自己反复修改提交了10几遍,第10个测试点仍然TLE,然后写了一个dijkstra,然后过了,说明关于spfa它死了,哈哈
代码:
1:spfa算法第10个测试点TLE的代码,90分
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+1,inf=0x3f3f3f3f;
vector<pair<int,int> >e[maxn];
int n,m,s,t,f,a,b,c,d[maxn],ing[maxn],point[maxn],u[maxn],l,r,mid,ans;
inline bool spfa(int top)
{
memset(d,inf,sizeof(d));
memset(ing,0,sizeof(ing));
queue<int>q;
q.push(s);
d[s]=0;
ing[s]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
ing[now]=0;
for(int i=0;i<e[now].size();i++)
{
int v=e[now][i].first;
if(d[v]>d[now]+e[now][i].second&&point[v]<=top)
{
d[v]=d[now]+e[now][i].second;
if(ing[v])
continue;
q.push(v);
ing[v]=1;
}
}
}
return d[t]<=f;
}
int main()
{
ios::sync_with_stdio(0);
scanf("%d%d%d%d%d",&n,&m,&s,&t,&f);
for(int i=1;i<=n;i++)
{
scanf("%d",&point[i]);
u[i]=point[i];
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[a].push_back(make_pair(b,c));
e[b].push_back(make_pair(a,c));
}
sort(u+1,u+n+1);
if(spfa(inf)==false)
{
printf("%d\n",-1);
return 0;
}
l=1;
r=n;
ans=0;
while(l<=r)
{
mid=(l+r)/2;
if(spfa(u[mid])==true)
{
ans=u[mid];
r=mid-1;
}
else
{
l=mid+1;
}
}
printf("%d\n",max(ans,point[s]));
return 0;
}
2:dijkstra,ac代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+1,inf=0x3f3f3f3f;
vector<pair<int,int> >e[maxn];
int n,m,s,t,f,a,b,c,d[maxn],ing[maxn],point[maxn],u[maxn],l,r,mid,ans;
inline bool dijkstra(int top)
{
memset(d,inf,sizeof(d));
priority_queue<pair<int,int> >q;
q.push(make_pair(-d[s],s));
d[s]=0;
while(!q.empty())
{
int now=q.top().second;
q.pop();
for(int i=0;i<e[now].size();i++)
{
int v=e[now][i].first;
if(point[v]>top)
continue;
if(d[v]>d[now]+e[now][i].second)
{
d[v]=d[now]+e[now][i].second;
q.push(make_pair(-d[v],v));
}
}
}
return d[t]<=f;
}
//inline bool spfa(int top)
//{
// memset(d,inf,sizeof(d));
// memset(ing,0,sizeof(ing));
// queue<int>q;
// q.push(s);
// d[s]=0;
// ing[s]=1;
// while(!q.empty())
// {
// int now=q.front();
// q.pop();
// ing[now]=0;
// for(int i=0;i<e[now].size();i++)
// {
// int v=e[now][i].first;
// if(d[v]>d[now]+e[now][i].second&&point[v]<=top)
// {
// d[v]=d[now]+e[now][i].second;
// if(ing[v])
// continue;
// q.push(v);
// ing[v]=1;
// }
// }
// }
// return d[t]<=f;
//}
int main()
{
ios::sync_with_stdio(0);
scanf("%d%d%d%d%d",&n,&m,&s,&t,&f);
for(int i=1;i<=n;i++)
{
scanf("%d",&point[i]);
u[i]=point[i];
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[a].push_back(make_pair(b,c));
e[b].push_back(make_pair(a,c));
}
sort(u+1,u+n+1);
if(dijkstra(inf)==false)
{
printf("%d\n",-1);
return 0;
}
l=1;
r=n;
ans=0;
while(l<=r)
{
mid=(l+r)/2;
if(dijkstra(u[mid])==true)
{
ans=u[mid];
r=mid-1;
}
else
{
l=mid+1;
}
}
printf("%d\n",max(ans,point[s]));
return 0;
}