Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题

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

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 218  Solved: 86
[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

题解:

最短路

Orz Hzwer 的最短路。好神!!!

对于每个奶牛看守的区间[l,r],我们从l-1向r去连边权为1的边,然后从每个i(1<=i<=T)向i-1连边权为0的边(就是可以反向跑),跑最短路就可以了。

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

 

posted @ 2016-03-30 11:39  微弱的世界  阅读(270)  评论(0编辑  收藏  举报