zoukankan      html  css  js  c++  java
  • 洛谷P1951 收费站_NOI导刊2009提高(2)

    题目:https://www.luogu.org/problemnew/show/1951

    题目描述

    在某个遥远的国家里,有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:           输出样例#1:
    4 4 2 3 8        8
    8
    5
    6
    10
    2 1 2
    2 4 1
    1 3 4
    3 4 3

    说明

    【数据规模】

    对于60%的数据,满足n<=200,m<=10000,s<=200

    对于100%的数据,满足n<=10000,m<=50000,s<=1000000000

    对于100%的数据,满足ci<=1000000000,fi<=1000000000,可能有两条边连接着相同的城市。

    解析

    看到1000000000顿时感到很害怕,但后来发现这是边权。

    想了一会,没啥思路,orz。

    但看到1000000000这个貌似没用的数据,于是想到:如果没用出题人告你干啥,还整得这么大。

    这么大,只有二分了啊。。。。。。

     

    好了,二分最大费用,跑spfa。美滋滋地过了样例,然后美滋滋地提交,然后。。。。。。

    spfa大暴力代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<vector>
     7 #include<queue>
     8 using namespace std;
     9 #define ll long long
    10 struct line{
    11     ll from,to;
    12     ll d;
    13 };
    14 vector<line> edge;
    15 vector<ll> G[10010];
    16 ll n,m,s,e,V; //s start e end v rongliang
    17 ll v[10010];
    18 ll ra,rb,rc;
    19 ll l,r,mid,ans;
    20 ll dis[10010];
    21 bool vis[10010];
    22 void addedge(ll from,ll to,ll val){
    23     edge.push_back((line){from,to,val});
    24     int m=edge.size();
    25     G[from].push_back(m-1);
    26 }
    27 bool check(ll maxv){
    28     if (maxv<v[s]) return false;
    29     memset(dis,0x3f,sizeof(dis));
    30     memset(vis,false,sizeof(vis));
    31     queue<ll> q;
    32     q.push(s);
    33     vis[s]=true;
    34     dis[s]=0;
    35     while (!q.empty()){
    36         int x=q.front();
    37         q.pop();
    38         vis[x]=false;
    39         for (ll i=0;i<G[x].size();++i){
    40             ll to=edge[G[x][i]].to;
    41             ll val=edge[G[x][i]].d;
    42             if (v[to]>maxv) continue;
    43             if (dis[to]>dis[x]+val){
    44                 dis[to]=dis[x]+val;
    45                 if (!vis[to]){
    46                     vis[to]=true;
    47                     q.push(to);
    48                 }
    49             }
    50         }
    51     }
    52     if (dis[e]>V) return false;
    53     return true;
    54 }
    55 int main(){
    56     scanf("%lld%lld%lld%lld%lld",&n,&m,&s,&e,&V);
    57     for (ll i=1;i<=n;++i){
    58         scanf("%lld",&v[i]);
    59     }
    60     for (ll i=1;i<=m;++i){
    61         scanf("%lld%lld%lld",&ra,&rb,&rc);
    62         addedge(ra,rb,rc);
    63         addedge(rb,ra,rc);
    64     }
    65     l=0; r=1000000000;
    66     while (l<=r){
    67         mid=(l+r)>>1;
    68         if (check(mid)){
    69             ans=mid;
    70             r=mid-1;
    71         }else{
    72             l=mid+1;
    73         }
    74     }
    75     printf("%d",ans);
    76     return 0;
    77 }
    View Code

    哇无良出题人卡spfa啊啊啊orz。

    没办法,上迪杰斯特拉吧。

    我把-1吃了orz。

    最后,终于ac。

    考试前老师出问题orz。

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<vector>
     7 #include<queue>
     8 using namespace std;
     9 #define ll long long
    10 struct line{
    11     ll from,to;
    12     ll d;
    13 };
    14 vector<line> edge;
    15 vector<ll> G[10010];
    16 struct node{
    17     ll pos,d;
    18     bool operator < (const node &x)const{
    19         return d>x.d;
    20     }
    21 }uu,vv;
    22 priority_queue<node> que;
    23 ll n,m,s,e,V; //s start e end v rongliang
    24 ll v[10010];
    25 ll ra,rb,rc;
    26 ll l,r,mid,ans;
    27 ll dis[10010];
    28 bool vis[10010];
    29 ll index_[10010],tot;
    30 void addedge(ll from,ll to,ll val){
    31     edge.push_back((line){from,to,val});
    32     int m=edge.size();
    33     G[from].push_back(m-1);
    34 }
    35 bool check(ll maxv){
    36     if (maxv<v[s]) return false;
    37     memset(dis,0x3f,sizeof(dis));
    38     memset(vis,false,sizeof(vis));
    39     while (!que.empty()) que.pop();
    40     dis[s]=0;
    41     que.push((node){s,0});
    42     while (!que.empty()){
    43         uu=que.top(); que.pop();
    44         if (vis[uu.pos]) continue;
    45         vis[uu.pos]=true;
    46         for (ll i=0;i<G[uu.pos].size();++i){
    47             ll to=edge[G[uu.pos][i]].to;
    48             ll val=edge[G[uu.pos][i]].d;
    49             if (v[to]>maxv) continue;
    50             if (dis[to]<=dis[uu.pos]+val) continue;
    51             dis[to]=dis[uu.pos]+val;
    52             que.push((node){to,dis[to]});
    53         }
    54     }
    55     return dis[e]<=V;
    56 }
    57 int main(){
    58     scanf("%lld%lld%lld%lld%lld",&n,&m,&s,&e,&V);
    59     for (ll i=1;i<=n;++i){
    60         scanf("%lld",&v[i]);
    61         index_[i]=v[i];
    62     }
    63     for (ll i=1;i<=m;++i){
    64         scanf("%lld%lld%lld",&ra,&rb,&rc);
    65         addedge(ra,rb,rc);
    66         addedge(rb,ra,rc);
    67     }
    68     sort(index_+1,index_+1+n);
    69     tot=unique(index_+1,index_+1+n)-(index_+1);
    70     l=1; r=tot;
    71     if (!check(index_[r])){
    72         printf("-1");
    73         return 0;
    74     }
    75     while (l<=r){
    76         mid=(l+r)>>1;
    77         if (check(index_[mid])){
    78             ans=index_[mid];
    79             r=mid-1;
    80         }else{
    81             l=mid+1;
    82         }
    83     }
    84     printf("%d",ans);
    85     return 0;
    86 }
  • 相关阅读:
    2021昆明站K-Riichi!!(麻将)
    数据结构 Week 3 --- dsu on tree 和 点分治
    数据结构 Week 2 --- 平衡树
    数据结构 Week 1 --- 从线段树到主席树
    一些思维题(三)
    一些思维题(二)
    2021ICPC昆明站总结及补题
    2021ICPC昆明M题 非主席树做法
    2020ICPC昆明参赛
    记5.28leetcode简单题
  • 原文地址:https://www.cnblogs.com/gjc1124646822/p/7795386.html
Copyright © 2011-2022 走看看