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

    P1951 收费站_NOI导刊2009提高(2)

    题目描述

    在某个遥远的国家里,有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
    8
    5
    6
    10
    2 1 2
    2 4 1
    1 3 4
    3 4 3
    
    输出样例#1:
    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);
    }
    30分 二分答案+暴力check
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxn 10010
    using namespace std;
    int n,m,s,t,g,num,head[maxn],w[maxn],f[maxn],mid,dis[maxn];
    bool vis[maxn];
    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;
    }
    struct Node{
        int id,dist;
        bool operator < (const Node b)const{
            return dist>b.dist;
        }
    };
    Node make_node(int x,int y){
        Node res;
        res.id=x;res.dist=y;
        return res;
    }
    bool Dij(int limit){
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        priority_queue<Node>q;
        q.push(make_node(s,0));
        dis[s]=0;
        while(!q.empty()){
            Node cur=q.top();q.pop();int now=cur.id;
            if(w[now]>limit)continue;
            if(vis[now])continue;
            vis[now]=1;
            for(int i=head[now];i;i=e[i].pre){
                int to=e[i].to;
                if(w[to]>limit)continue;
                if(dis[to]>dis[now]+e[i].v){
                    dis[to]=dis[now]+e[i].v;
                    q.push(make_node(to,dis[to]));
                }
            }
        }
        return dis[t]<=g;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d%d%d%d%d",&n,&m,&s,&t,&g);
        for(int i=1;i<=n;i++){
            scanf("%d",&w[i]);
            f[i]=w[i];
        }
        sort(f+1,f+n+1);
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z);Insert(y,x,z);
        }
        int l=1,r=n,ans=-1;
        while(l<=r){
            mid=(l+r)>>1;
            if(Dij(f[mid]))ans=f[mid],r=mid-1;
            else l=mid+1;
        }
        printf("%d",ans);
        return 0;
    }
    100分 二分答案+堆优化Dij
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<deque>
    #define maxn 10010
    using namespace std;
    int n,m,s,t,g,num,head[maxn],dis[maxn],w[maxn],f[maxn];
    bool vis[maxn];
    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;
    }
    bool spfa(int limit){
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        deque<int>q;
        q.push_back(s);
        dis[s]=0;vis[s]=1;
        while(!q.empty()){
            int now=q.front();q.pop_front();vis[now]=0;
            if(w[now]>limit)continue;
            for(int i=head[now];i;i=e[i].pre){
                int to=e[i].to;
                if(w[to]>limit)continue;
                if(dis[to]>dis[now]+e[i].v){
                    dis[to]=dis[now]+e[i].v;
                    if(!vis[to]){
                        vis[to]=1;
                        if(!q.empty()&&dis[to]<dis[q.front()])q.push_front(to);
                        else q.push_back(to);
                    }
                }
            }
        }
        return dis[t]<=g;
    }
    int main(){
        scanf("%d%d%d%d%d",&n,&m,&s,&t,&g);
        for(int i=1;i<=n;i++){
            scanf("%d",&w[i]);
            f[i]=w[i];
        }
        sort(f+1,f+n+1);
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z);Insert(y,x,z);
        }
        int l=1,r=n,ans=-1;
        while(l<=r){
            int mid=(l+r)>>1;
            if(spfa(f[mid]))ans=f[mid],r=mid-1;
            else l=mid+1;
        }
        printf("%d",ans);
    }
    100分 二分答案+SLF优化SPFA
  • 相关阅读:
    Python paramik
    JavaScript和DOM
    HTML和CSS
    salt基本使用之二(2)
    nginx+php与apache+php性能对比
    varnish状态引擎2
    varnish状态引擎1
    varnish简介
    使用memcached实现tomcat集群session共享
    php安装redis扩展连接redis服务器
  • 原文地址:https://www.cnblogs.com/thmyl/p/7642831.html
Copyright © 2011-2022 走看看