zoukankan      html  css  js  c++  java
  • Gym 101873C

    题目链接:http://codeforces.com/gym/101873/problem/C

    题意:

    这是七月的又一个阳光灿烂的日子,你决定和你的小女儿一起度过快乐的一天。因为她真的很喜欢隔壁镇上的仙女公园,所以你决定到那儿去玩一天。

    你妻子同意开车送你去公园接你。她非常准时,所以她确切地告诉你她什么时候会到公园的前门来接你,而你必须恰好在那个时间到那里。因为你显然也不想在外面等,这样会让你的小女儿伤心——她本可以在公园里多待些时间。

    现在你必须考虑游玩计划。你知道你什么时候到达,什么时候离开。公园由若干游玩设施组成,两两之间由人行道相连。进入公园是免费的,但你每次使用在公园里的某项设施,都必须付一次相应费用。你已经知道玩每一项游玩设施各自需要多长时间、花多少钱。

    当你穿过公园时,你显然不能在沿着公园走的时候跳过游乐设施(即使乔伊已经用了),否则乔伊会很伤心。因为乔非常喜欢公园,她很乐意玩同一个项目不止一次。在两个游乐项目之间行走需要一定的时间。

    因为你是一个有计划的家长,所以当你在公园的时候,你要尽量少花钱。你能计算至少要花多少钱吗?

    输入:

    一行,一个整数 $x(1 le x le 1e3)$ 代表你们在公园玩的确切时间。

    一行,三个整数 $n,m,t(1 le n,m,t le 1e3)$,代表有 $n$ 个娱乐设施, 之间有 $m$ 条人行道连接,走人行道需要花费 $t$ 分钟。

    $m$ 行,每行 $a,b$ 代表设施 $a,b$ 之间有一条小路。

    $n$ 行,每行 $t,p$ 代表该项游乐设施花费 $t$ 分钟,$p$ 元。

    你从设施 $1$ 出发,最后必须回到设施 $1$。

    Sample Input 1
    4
    4 4 1
    1 2
    2 3
    3 4
    4 1
    1 2
    2 1
    5 4
    3 3
    Sample Output 1
    8

    Sample Input 2
    6
    4 4 1
    1 2
    2 3
    3 4
    4 1
    1 2
    2 1
    5 4
    3 3
    Sample Output 2
    5

    题解:

    按花费钱的数量跑最短路,$dist[v][k]$ 表示在 $k$ 时刻走到点 $v$ 最少花费 $dist[v][t]$ 元。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+10;
    
    int x;
    int n,m,w;
    int t[maxn],p[maxn];
    
    struct Edge{
        int u,v,w;
        Edge(){}
        Edge(int _u,int _v){u=_u, v=_v;}
    };
    vector<Edge> E;
    vector<int> G[maxn];
    void addedge(int u,int v)
    {
        E.push_back(Edge(u,v));
        G[u].push_back(E.size()-1);
    }
    
    struct Qnode
    {
        int v,k,d;
        Qnode(){}
        Qnode(int _v,int _k,int _d) {
            v=_v, k=_k, d=_d;
        }
        bool operator<(const Qnode& oth)const {
            return d>oth.d;
        }
    };
    int dist[maxn][maxn];
    bool vis[maxn][maxn];
    void dijkstra()
    {
        memset(dist,0x3f,sizeof(dist));
        memset(vis,0,sizeof(vis));
    
        priority_queue<Qnode> Q;
        if(t[1]<=x) dist[1][t[1]]=p[1];
        else return;
        Q.push(Qnode(1,t[1],p[1]));
        while(!Q.empty())
        {
            int u=Q.top().v, k=Q.top().k; Q.pop();
            if(vis[u][k]) continue;
            vis[u][k]=1;
            if(k+t[u]<=x && dist[u][k+t[u]]>dist[u][k]+p[u])
            {
                dist[u][k+t[u]]=dist[u][k]+p[u];
                Q.push(Qnode(u,k+t[u],dist[u][k+t[u]]));
            }
            for(int i=0;i<G[u].size();i++)
            {
                Edge &e=E[G[u][i]]; int v=e.v;
                if(k+w+t[v]>x) continue;
                if(!vis[v][k+w+t[v]] && dist[v][k+w+t[v]]>dist[u][k]+p[v])
                {
                    dist[v][k+w+t[v]]=dist[u][k]+p[v];
                    Q.push(Qnode(v,k+w+t[v],dist[v][k+w+t[v]]));
                }
            }
        }
    }
    
    int main()
    {
        cin>>x>>n>>m>>w;
        for(int i=1,u,v;i<=m;i++)
        {
            cin>>u>>v;
            addedge(u,v);
            addedge(v,u);
        }
        for(int i=1;i<=n;i++) cin>>t[i]>>p[i];
        dijkstra();
        if(vis[1][x]) cout<<dist[1][x]<<endl;
        else cout<<"It is a trap."<<endl;
    }
  • 相关阅读:
    条件极值(1):隐函数极值问题
    从隐函数存在定理到隐函数定理
    吐槽教科书:不先行解释表达偏导数的符号
    8237dma的四种传送方式简介
    多线程中wait和notify的理解与使用
    ★三个和尚与机构臃肿的故事
    ★三个和尚与机构臃肿的故事
    常用的组播保留地址列表
    常用的组播保留地址列表
    谈谈IT界8大恐怖预言!
  • 原文地址:https://www.cnblogs.com/dilthey/p/9928485.html
Copyright © 2011-2022 走看看