洛谷P1951 收费站_NOI导刊2009提高
Posted Soda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1951 收费站_NOI导刊2009提高相关的知识,希望对你有一定的参考价值。
题目描述
在某个遥远的国家里,有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.
输入输出样例
4 4 2 3 8 8 5 6 10 2 1 2 2 4 1 1 3 4 3 4 3
8
说明
【数据规模】
对于60%的数据,满足n<=200,m<=10000,s<=200
对于100%的数据,满足n<=10000,m<=50000,s<=1000000000
对于100%的数据,满足ci<=1000000000,fi<=1000000000,可能有两条边连接着相同的城市。
#include<iostream> #include<cstdio> #include<cstring> #define maxn 10010 using namespace std; int n,m,s,t,g,w[maxn],num,head[maxn],mid; bool vis[maxn],ok; struct node{ int to,pre,v; }e[100010]; void Insert(int from,int to,int v){ e[++num].to=to; e[num].v=v; e[num].pre=head[from]; head[from]=num; } void dfs(int now,int gg){ if(now==t){ ok=1; return; } if(ok)return; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(!vis[to]&&w[to]<=mid&&(gg-e[i].v>=0))dfs(to,gg-e[i].v); } } bool check(){ memset(vis,0,sizeof(vis));ok=0; vis[s]=1; dfs(s,g); if(ok)return 1; return 0; } int main(){ int x,y,z; scanf("%d%d%d%d%d",&n,&m,&s,&t,&g); int l=0x7fffffff,r=0; for(int i=1;i<=n;i++){ scanf("%d",&w[i]); r=max(r,w[i]); } l=w[s]; for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); Insert(x,y,z);Insert(y,x,z); } int ans=-1; while(l<=r){ mid=(l+r)>>1; if(check())ans=mid,r=mid-1; else l=mid+1; } printf("%d",ans); }
以上是关于洛谷P1951 收费站_NOI导刊2009提高的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P1795 无穷的序列_NOI导刊2010提高(05)