【题目描述】
在某个遥远的国家里,有n 个城市。编号为1,2,3,……,n。
这个国家的政府修建了m 条双向的公路。每条公路连接着两个城市。沿着
某条公路,开车从一个城市到另一个城市,需要花费一定的汽油。
开车每经过一个城市,都会被收取一定的费用(包括起点和终点城市)。所
有的收费站都在城市中,在城市间的公路上没有任何的收费站。
小红现在要开车从城市u 到城市v(1<=u,v<=n)。她的车最多可以装下s
升的汽油。在出发的时候,车的油箱是满的,并且她在路上不想加油。
在路上,每经过一个城市,她要交一定的费用。如果她某次交的费用比较
多,她的心情就会变得很糟。所以她想知道,在她能到达目的地的前提下,她交
的费用中最多的一次最少是多少。这个问题对于她来说太难了,于是她找到了聪
明的你,你能帮帮她吗?
【输入格式】
第一行5 个正整数,n,m,u,v,s。分别表示有n 个城市,m 条公路,
从城市u 到城市v,车的油箱的容量为s 升。
接下来有n 行,每行1 个正整数,fi。表示经过城市i,需要交费fi 元。
再接下来有m 行,每行3 个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市
ai 和城市bi 之间有一条公路,如果从城市ai 到城市bi,或者从城市bi 到城市ai,
需要用ci 升汽油。
【输出格式】
仅一个整数,表示小红交费最多的一次的最小值。
如果她无法到达城市v,输出-1。
【输入样例1】
4 4 2 3 8
8561
0
2 1 2
2 4 1
1 3 4
3 4 3
【输出样例1】
8
【输入样例2】
4 4 2 3 3
8561
0
2 1 2
2 4 1
1 3 4
3 4 3
【输出样例2】
-1
【数据规模】
对于60%的数据,满足n<=200,m<=10000,s<=200
对于100%的数据,满足n<=10000,m<=50000,s<=1000000000
对于100%的数据,满足ci<=1000000000,fi<=1000000000,可能有两条边
在某个遥远的国家里,有n 个城市。编号为1,2,3,……,n。
这个国家的政府修建了m 条双向的公路。每条公路连接着两个城市。沿着
某条公路,开车从一个城市到另一个城市,需要花费一定的汽油。
开车每经过一个城市,都会被收取一定的费用(包括起点和终点城市)。所
有的收费站都在城市中,在城市间的公路上没有任何的收费站。
小红现在要开车从城市u 到城市v(1<=u,v<=n)。她的车最多可以装下s
升的汽油。在出发的时候,车的油箱是满的,并且她在路上不想加油。
在路上,每经过一个城市,她要交一定的费用。如果她某次交的费用比较
多,她的心情就会变得很糟。所以她想知道,在她能到达目的地的前提下,她交
的费用中最多的一次最少是多少。这个问题对于她来说太难了,于是她找到了聪
明的你,你能帮帮她吗?
【输入格式】
第一行5 个正整数,n,m,u,v,s。分别表示有n 个城市,m 条公路,
从城市u 到城市v,车的油箱的容量为s 升。
接下来有n 行,每行1 个正整数,fi。表示经过城市i,需要交费fi 元。
再接下来有m 行,每行3 个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市
ai 和城市bi 之间有一条公路,如果从城市ai 到城市bi,或者从城市bi 到城市ai,
需要用ci 升汽油。
【输出格式】
仅一个整数,表示小红交费最多的一次的最小值。
如果她无法到达城市v,输出-1。
【输入样例1】
4 4 2 3 8
8561
0
2 1 2
2 4 1
1 3 4
3 4 3
【输出样例1】
8
【输入样例2】
4 4 2 3 3
8561
0
2 1 2
2 4 1
1 3 4
3 4 3
【输出样例2】
-1
【数据规模】
对于60%的数据,满足n<=200,m<=10000,s<=200
对于100%的数据,满足n<=10000,m<=50000,s<=1000000000
对于100%的数据,满足ci<=1000000000,fi<=1000000000,可能有两条边
连接着相同的城市。
分析:没经过一个城市,就会收取费用,求在满足油量小于S的情况下最大的s的最小值。
首先转换题型:对于一个最大费用,判断是否在这个费用的限制下能u—>v
二分这个最大费用
(spfa会爆一个点)
#include<vector>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10010
using namespace std;
const int inf=1<<30;
vector <int>e[N];
int m,n,u,v,s;
int f[N],minv[N],maps[N][N],vis[N],dist[N];
void add(int u,int v,int w){
maps[u][v]=maps[v][u]=w;
e[u].push_back(v);
e[v].push_back(u);
}
void init(){
scanf("%d%d%d%d%d",&n,&m,&u,&v,&s);
for (int i=1;i<=n;i++) scanf("%d",&f[i]);
int a,b,c;
for (int i=1;i<=m*2;i+=2)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
}
bool check(int cost){
queue <int>q;
memset(vis,0,sizeof vis);
vis[u]=1;
for (int i=1;i<=n;i++) dist[i]=inf;
dist[u]=0;
q.push(u);
while (!q.empty())
{
int top=q.front();q.pop();
vis[top]=1;
for (int i=0;i<e[top].size();i++)
{
int t=e[top][i];
//if (maps[top][t] >cost) continue;
if (f[top]>cost) continue;
if (dist[top]+maps[top][t] < dist[t])
{
dist[t] = dist[top]+maps[top][t];
q.push(top);
if (!vis[t])
{
q.push(t);
vis[t]=1;
}
}
}
vis[top]=0;
}
if (dist[v] <= cost) return true;
return false;
}
int main(){
freopen("cost.in","r",stdin);
freopen("cost.out","w",stdout);
init();
int l = 1,r = 1000000000;
while (l < r)
{
int mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
if (r==1000000000) cout << -1<<endl;
else cout << r;
return 0;
}