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;
}

 

posted @ 2016-09-30 15:56  ACforever  阅读(360)  评论(0编辑  收藏  举报