描述
今天,他们在打一张叫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时刻到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; }