Vijos1404 遭遇战 最短路,dijkstra,堆

P1404遭遇战
 
 

背景

你知道吗,SQ Class的人都很喜欢打CS。(不知道CS是什么的人不用参加这次比赛)。

描述

今天,他们在打一张叫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名。

来源

SQ CLASS公开编程竞赛2008——Problem D
Source: WindTalker, liuichou, royZhang

 

题解:

dijkstra+堆

这道题就是要求用最少花费去覆盖区间,可以想到转化为dp。

我是用最短路跑的这道题。

注意:1.坐标可能到0

2. si和ei可能包括S和E

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define MAXN 10010
 4 #define INF 1e9
 5 struct node
 6 {
 7     int begin,end,value,next;
 8 }edge[10*MAXN];
 9 int cnt,Head[MAXN*10],n,dis[MAXN*10],Heap[MAXN*10],pos[MAXN*10],SIZE,ee;
10 int read()
11 {
12     int s=0,fh=1;char ch=getchar();
13     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
14     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
15     return s*fh;
16 }
17 void addedge(int bb,int ee,int vv)
18 {
19     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
20 }
21 void addedge1(int bb,int ee,int vv)
22 {
23     addedge(bb,ee,vv);addedge(ee,bb,vv);
24 }
25 void Push1(int k)
26 {
27     int now=k,root;
28     while(now>1)
29     {
30         root=now/2;
31         if(dis[Heap[root]]<=dis[Heap[now]])return;
32         swap(Heap[root],Heap[now]);
33         swap(pos[Heap[root]],pos[Heap[now]]);
34         now=root;
35     }
36 }
37 void Insert(int k)
38 {
39     Heap[++SIZE]=k;pos[k]=SIZE;Push1(SIZE);
40 }
41 void Pop1(int k)
42 {
43     int now,root=k;
44     pos[Heap[k]]=0;Heap[k]=Heap[SIZE--];if(k>0)pos[Heap[k]]=k;
45     while(root<=SIZE/2)
46     {
47         now=root*2;
48         if(now<SIZE&&dis[Heap[now+1]]<dis[Heap[now]])now++;
49         if(dis[Heap[root]]<=dis[Heap[now]])return;
50         swap(Heap[root],Heap[now]);
51         swap(pos[Heap[root]],pos[Heap[now]]);
52         root=now;
53     }
54 }
55 int dijkstra(int start,int end)
56 {
57     int i,u,v;
58     for(i=0;i<=ee;i++)dis[i]=INF;dis[start]=0;
59     for(i=0;i<=ee;i++)Insert(i);
60     while(SIZE>0)
61     {
62         u=Heap[1];Pop1(pos[u]);
63         for(i=Head[u];i!=-1;i=edge[i].next)
64         {
65             v=edge[i].end;
66             if(dis[v]>dis[u]+edge[i].value){dis[v]=dis[u]+edge[i].value;Push1(pos[v]);}
67         }
68     }
69     return dis[end];
70 }
71 int main()
72 {
73     int s,e,S,E,C,i,DIS;
74     n=read();s=read();e=read();
75     memset(Head,-1,sizeof(Head));cnt=1;
76     //for(i=s;i<=e+1;i++)addedge(i+1,i,0);
77     for(i=s;i<=e+1;i++)addedge(i+1,i,0);
78     ee=e+1;
79     for(i=1;i<=n;i++)
80     {
81         S=read();E=read();C=read();
82         addedge(max(S,s),min(E+1,ee),C);
83     }
84     DIS=dijkstra(s,e+1);
85     if(DIS==INF)printf("-1");
86     else printf("%d",DIS);
87     fclose(stdin);
88     fclose(stdout);
89     return 0;
90 }

 

posted @ 2016-05-11 14:56  微弱的世界  阅读(223)  评论(0编辑  收藏  举报