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;
}
}