Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题
3389: [Usaco2004 Dec]Cleaning Shifts安排值班
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 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
题解:
最短路
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 }