【百度之星資格賽】F:百科蝌蚪團
時間限制: 1000ms 記憶體限制: 65536kB
描述
百度百科有一支神奇的隊伍,他們叫自己“百科蝌蚪團”。為了更好的讓蝌蚪團的成員們安排工作,百度百科的運營團隊定出了一個24小時制的時間表。例如:
1. 每個蝌蚪團成員工作時長相同;
2. 必須安排蝌蚪團成員在他們方便的時間段工作;
3. 蝌蚪團成員安排時間最小安排時間節點(開始工作或停止工作)為半小時,比如04:00或04:30,而不是04:15;
4. 蝌蚪團成員一天在百度百科工作的時間是有上限的,他們會根據自己的情況給出上限。
5. 在特定時間段內必須有一定數量的蝌蚪團成員工作,以保證百度百科不斷的進步
請幫運營團隊計算一下,能保持24小時穩定在崗的蝌蚪團最少成員的數量。如果有2個蝌蚪團成員工作結束,同時另2個蝌蚪團成員開始工作,這段時間都算有2各成員穩定在崗。
輸入
輸入有多組,每組測試資料以一個整數N開頭(1 ≤ N ≤ 50),表示蝌蚪團的成員數。緊接著,我們會有N個數據塊,每一個數據塊對應了一名蝌蚪團成員的日程情況。
每個資料塊以兩個整數開始,分別為K(1 ≤ K ≤ 50)和M(1 ≤ M ≤ 1440),用空格隔開。K表示這個資料塊對應蝌蚪團成員方便的時間段的數量,M表示這個成員願意每天在百度百科工作的最長分鐘數。接下去的K行中,每行包括兩個時間,分別表示成“HH:MM”的格式,以空格分隔,分別對應了該蝌蚪團成員一個方便的時間段的開始時間、結束時間;例如09:00 10:00表明他在早上九點到十點的時間段是方便的,可以在百度百科工作。如果兩個時間相同,則說明這個他全天都是方便的。
最後一組資料的N為0,表示輸入結束。
輸出
對於每組資料,輸出為一個整數,佔一行。表示能保持24小時穩定在崗的蝌蚪團最少成員的數量。
樣例輸入
5
1 720
18:00 12:00
1 1080
00:00 23:00
1 1080
00:00 20:00
1 1050
06:00 00:00
1 360
18:00 00:00
3
1 540
00:00 00:00
3 480
08:00 10:00
09:00 12:00
13:00 19:00
1 420
17:00 00:00
3
1 1440
00:00 00:00
1 720
00:00 12:15
1 720
12:05 00:15
0
樣例輸出
2
1
1
【題解】
網路流建圖。
每半個小時作為一個點,至於建邊,我想就很簡單了。。。
【程式碼】
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int oo=200000,N=400; struct edge { int x,y,f,next,op; }e[20000]; int h[N],d[N],p[N],now[N],num[N],times[N]; bool a[55][55],b[55][1444]; int n,s,t,tot; void ins(int x,int y,int f) { e[++tot].x=x;e[tot].y=y; e[tot].next=h[x];e[tot].f=f; h[x]=tot; e[++tot].x=y;e[tot].y=x; e[tot].next=h[y];e[tot].f=0; h[y]=tot; e[tot].op=tot-1;e[tot-1].op=tot; } int isap() { int flow=0,aug=oo,u,v,tmp,i,j,ff; for (i=0;i<=t;i++) { d[i]=0;p[i]=-1; num[i]=0;now[i]=h[i]; } num[0]=t+1;u=s; while (d[s]<t+1) { for (ff=0,i=now[u];i;i=e[i].next) { v=e[i].y; if (e[i].f && d[u]==d[v]+1) { ff=1; if (e[i].f<aug) aug=e[i].f; p[v]=i;now[u]=i; u=v; if (u==t) { flow+=aug; while (u!=s) { j=p[u]; e[j].f-=aug; e[e[j].op].f+=aug; u=e[j].x; } aug=oo; } break; } } if (ff) continue; num[d[u]]--; if (!num[d[u]]) return flow; tmp=t+1; for (i=h[u];i;i=e[i].next) { v=e[i].y; if (e[i].f && d[v]<tmp) { tmp=d[v];now[u]=i; } } d[u]=tmp+1; num[d[u]]++; if (u!=s) u=e[p[u]].x; } return flow; } void build(int x) { int i,j; s=0;t=n+97; memset(h,0,sizeof(h)); tot=0; for (i=1;i<=n;i++) ins(s,i,times[i]); for (i=1;i<=n;i++) for (j=0;j<48;j++) if (a[i][j]) ins(i,n+j+1,1); for (i=0;i<48;i++) ins(n+i+1,n+49+i,x); for (i=0;i<48;i++) ins(n+49+i,t,x); } void fill(int id,int x,int y) { for (int i=x;i<y;i++) b[id][i]=true; } int main() { freopen("in.txt","r",stdin); //freopen("ou.txt","w",stdout); int i,j,k; while (cin >> n) { if (n==0) break; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for (i=1;i<=n;i++) { int ss; cin >> ss >> times[i]; times[i]/=30; for (j=1;j<=ss;j++) { int aa,bb,cc,dd,t1,t2; scanf("%d:%d %d:%d\n",&aa,&bb,&cc,&dd); t1=aa*60+bb; t2=cc*60+dd; if (t1==t2) fill(i,0,1440); else if (t1<t2) fill(i,t1,t2); else { fill(i,t1,1440);fill(i,0,t2); } } } for (i=1;i<=n;i++) for (j=0;j<48;j++) { bool ff=true; for (k=j*30;k<j*30+30;k++) if (!b[i][k]) ff=false; a[i][j]=ff; } for (i=n;i;i--) { build(i); int tmp=isap(); if (tmp>=i*48) break; } cout << i << endl; } }