【百度之星資格賽】F:百科蝌蚪團

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章