• vijos1404 遭遇战


    描述

    今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC的人誓死不屈,即将于恐怖分子展开激战,准备让一个人守着A区,这样恐怖分子就不能炸掉服务器了。(一个人就能守住??这人是机械战警还是霹雳游侠?)
    但是问题随之出现了,由于DustII中风景秀丽,而且不收门票,所以n名反恐精英们很喜欢在这里散步,喝茶。他们不愿意去单独守在荒无人烟的A区,在指挥官的一再命令下,他们终于妥协了,但是他们每个人都要求能继续旅游,于是给出了自己的空闲时间,而且你强大的情报系统告诉了你恐怖份子计划的进攻时间(从s时刻到e时刻)。

    当然,精明的SQC成员不会为你免费服务,他们还要收取一定的佣金(注意,只要你聘用这个队员,不论他的执勤时间多少,都要付所有被要求的佣金)。身为指挥官的你,看看口袋里不多的资金(上头真抠!),需要安排一个计划,雇佣一些队员,让他们在保证在进攻时间里每时每刻都有人员执勤,花费的最少资金。

    格式

    输入格式

    第一行是三个整数n(1≤n≤10000),s和e(1≤s≤e≤90000)。

    接下来n行,描述每个反恐队员的信息:空闲的时间si, ei(1≤si≤ei≤90000)和佣金ci(1≤ci≤300000)。

    输出格式

    一个整数,最少需支付的佣金,如果无解,输出“-1”。

    样例1

    样例输入1[复制]

     
    3 1 5
    1 3 3
    4 5 2
    1 1 1

    样例输出1[复制]

     
    5

    限制

     

    提示

    敌人从1时刻到4时刻要来进攻,一共有3名反恐队员。第1名从1时刻到3时刻有空,要3元钱(买糖都不够??)。以此类推。

    一共要付5元钱,选用第1名和第2名。

    /*
    可以用最短路处理这个类dp问题,麻烦的地方在于建图
    考虑由于一个人可以干任意时间,代价相同可以往前连一条0权边
    一个人,当支付了他的佣金之后考虑可转移到得天数,一定不小于开始的时间(如果小于,那么我不要你也能到达这一天满足要求,那么我干嘛要你)
    于是就可以把所有的天对应的点都向前连一条0权边
    */
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    const int maxn = 100000;
    const ll inf = 98765432123LL;
    int n,s,t;
    int head[maxn],cnt;
    ll dis[maxn];
    bool vis[maxn];
    struct edge{
        int v;
        int w;
        int nxt;
    }e[maxn*3];
    int read(){
        char ch=getchar();
        int f=1,x=0;
        while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
        while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
        return x*f;
    }
    void ins(int u,int v,int w){
        cnt++;
        e[cnt].v = v;
        e[cnt].w = w;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    void spfa(){
        for(int i = 0;i < 95000;i++) dis[i] = inf;
        queue<int> q;
        int now,to;
        vis[s] = true;
        dis[s] = 0;
        q.push(s);
        while(!q.empty()){
            now = q.front();
            q.pop();
            for(int i = head[now];i;i = e[i].nxt){
                to = e[i].v ;
                if(dis[to] > dis[now] + e[i].w){
                    dis[to] = dis[now] + e[i].w;
                    if(!vis[to]){
                        vis[to] = true;
                        q.push(to);
                    }
                }
            }
            vis[now] = false;
        }
        if(dis[t+1] < inf) cout<<dis[t+1];
        else cout<<-1;
    }
    int main(){
        n = read();
        s = read();
        t = read();
        int a,b,c;
        for(int i = 1;i <= n;i++){
            a = read();
            b = read();
            c = read();
            ins(max(a,s),min(b+1,t+1),c);
        }
        for(int i = s;i <= t;i++) ins(i+1,i,0);
        spfa();
        return 0;
    }
  • 相关阅读:
    hdu 1164 Eddy's research I
    hdu 3794 Magic Coupon
    hdu 1460 完数
    hdu 1201 18岁生日
    求一组整数中所有素数之和
    备忘录
    c判断括弧是否匹配
    N!大整数阶乘问题
    计算一个人从出生到现在活了多少天
    java web.xml配置详解(转)
  • 原文地址:https://www.cnblogs.com/hyfer/p/5924028.html
Copyright © 2020-2023  润新知