3389: [Usaco2004 Dec]Cleaning Shifts安排值班

3389: [Usaco2004 Dec]Cleaning Shifts安排值班

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 102  Solved: 46
[Submit][Status][Discuss]

Description

    一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫
打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个时间段必需有奶牛在值班.  那么,最少需要动用多少奶牛参与值班呢?如果没有办法安排出合理的方案,就输出-1.

Input

 
    第1行:N,T.
    第2到N+1行:Si,Ei.

Output

 
    最少安排的奶牛数.

Sample Input


3 10
1 7
3 6
6 10

Sample Output


2


样例说明
奶牛1和奶牛3参与值班即可.

HINT

 

Source

Silver

 

题解:这道题做法有很多,比如:DP(虽然多半会TLE)、贪心、甚至最短路

DP:不用多说,就是通过各个区间进行对于前面的转移,所以需要用到一个快速的区间查询数据结构进行维护,但是很可惜,时限是1s,而T<=1000000,TLE是十有八九的事

贪心:显然,对于多个结束时间相同的区间来说,保留一个起始时间最长的即可,于是我们开始进行贪心

 1 /**************************************************************
 2     Problem: 3389
 3     User: HansBug
 4     Language: Pascal
 5     Result: Accepted
 6     Time:100 ms
 7     Memory:1008 kb
 8 ****************************************************************/
 9  
10 var
11    i,j,k,l,m,n,ans:longint;
12    a:array[0..100000,1..2] of longint;
13 function max(x,y:longint):longint;
14          begin
15               if x>y then max:=x else max:=y;
16          end;
17 procedure swap(var x,y:longint);
18           var z:longint;
19           begin
20                z:=x;x:=y;y:=z;
21           end;
22  
23 procedure sort(l,r:longint);
24           var i,j,x,y:longint;
25           begin
26                i:=l;j:=r;x:=a[(l+r) div 2,1];y:=a[(l+r) div 2,2];
27                repeat
28                      while (a[i,1]<x) or ((a[i,1]=x) and (a[i,2]<y)) do inc(i);
29                      while (a[j,1]>x) or ((a[j,1]=x) and (a[j,2]>y)) do dec(j);
30                      if i<=j then
31                         begin
32                              swap(a[i,1],a[j,1]);
33                              swap(a[i,2],a[j,2]);
34                              inc(i);dec(j);
35                         end;
36                until i>j;
37                if i<r then sort(i,r);
38                if l<j then sort(l,j);
39           end;
40 begin
41      readln(n,m);
42      a[0,1]:=0;a[0,2]:=0;
43      for i:=1 to n do readln(a[i,1],a[i,2]);
44      sort(1,n);ans:=0;
45      while l<m do
46            begin
47                 j:=l;
48                 while (k<n) and (a[k+1,1]<=(j+1)) do
49                       begin
50                            inc(k);
51                            l:=max(l,a[k,2]);
52                       end;
53                 if (k=n) and (a[k,2]<m) or (a[k+1,1]>(l+1)) then
54                    begin
55                         writeln(-1);
56                         halt;
57                    end;
58                 inc(ans);
59            end;
60      if l<m then writeln(-1) else writeln(ans);
61 end.   

最短路:这道题个人认为最神奇的做法就是最短路,我们可以以每个时间点为节点,对于所有的(i,i-1)连边权为0的有向边,对于数据所给的时间段(x,y),连(x-1,y)边权为1的有向边,然后求0到T的最短路即可,还有——对于P党来说一个很大的重点在于离散化,必须把一些只指向前一个节点而且边权还为0的给压缩,这样子可以节省大量时间,我原来简单的最短路居然TLE,离散化之后就AC了(HansBug:感谢phile神犇的离散化点子么么哒)

 1 /**************************************************************
 2     Problem: 3389
 3     User: HansBug
 4     Language: Pascal
 5     Result: Accepted
 6     Time:160 ms
 7     Memory:5132 kb
 8 ****************************************************************/
 9  
10 type
11     point=^node;
12     node=record
13                g,w:longint;
14                next:point;
15     end;
16 var
17    i,j,k,l,m,n,f,r:longint;
18    a,b:array[0..60000,1..3] of longint;
19    c,g:array[0..50000] of longint;
20    d:array[0..500000] of longint;
21    e:array[0..50000] of point;
22    p:point;
23 procedure add(x,y,z:longint);
24           var p:point;
25           begin
26                new(p);p^.g:=y;p^.w:=z;p^.next:=e[x];e[x]:=p;
27           end;
28 procedure swap(var x,y:longint);
29           var z:longint;
30           begin
31                z:=x;x:=y;y:=z;
32           end;
33 procedure sort(l,r:longint);
34           var i,j,x,y:longint;
35           begin
36                i:=l;j:=r;x:=b[(l+r) div 2,1];
37                repeat
38                      while b[i,1]<x do inc(i);
39                      while b[j,1]>x do dec(j);
40                      if i<=j then
41                         begin
42                              swap(b[i,1],b[j,1]);
43                              swap(b[i,2],b[j,2]);
44                              swap(b[i,3],b[j,3]);
45                              inc(i);dec(j);
46                         end;
47                until i>j;
48                if i<r then sort(i,r);
49                if l<j then sort(l,j);
50           end;
51  
52 begin
53      readln(n,m);
54      for i:=1 to n do
55          begin
56               readln(a[i,1],a[i,2]);a[i,1]:=a[i,1]-1;
57               b[i*2-1,1]:=a[i,1];b[i*2-1,2]:=i;b[i*2-1,3]:=1;
58               b[i*2,1]:=a[i,2];b[i*2,2]:=i;b[i*2,3]:=2;
59          end;
60      b[n*2+1,1]:=m;b[n*2+1,2]:=0;b[n*2+1,3]:=0;
61      sort(1,n*2);
62      b[0,1]:=0;
63      for i:=1 to n*2 do
64          begin
65               if b[i,1]<>b[i-1,1] then inc(j);
66               a[b[i,2],b[i,3]]:=j;
67          end;
68      if b[n*2+1,1]>b[n*2,1] then inc(j);
69      m:=j;
70      for i:=0 to m do e[i]:=nil;
71      for i:=m downto 1 do add(i,i-1,0);
72      for i:=1 to n do add(a[i,1],a[i,2],1);
73      fillchar(c,sizeof(c),0);fillchar(g,sizeof(g),0);
74      c[0]:=1;d[1]:=0;f:=1;r:=2;g[0]:=1;
75      while f<r do
76            begin
77                 p:=e[d[f]];
78                 while p<>nil do
79                       begin
80                            if (c[p^.g]=0) or (c[p^.g]>(c[d[f]]+p^.w)) then
81                               begin
82                                    c[p^.g]:=c[d[f]]+p^.w;
83                                    if g[p^.g]=0 then
84                                       begin
85                                            g[p^.g]:=1;
86                                            d[r]:=p^.g;
87                                            inc(r);
88                                       end;
89                               end;
90                            p:=p^.next;
91                       end;
92                 inc(f);
93                 g[d[f]]:=0;
94            end;
95      for i:=0 to m do dec(c[i]);
96      writeln(c[m]);
97      readln;
98 end.      

 

 

posted @ 2015-04-14 21:20  HansBug  阅读(319)  评论(0编辑  收藏  举报