It Can Be Arranged

来源:互联网 发布:未来的大数据 编辑:程序博客网 时间:2024/06/05 00:19

It Can Be Arranged

这里写图片描述
.
.
题意:有n种课程,每个教室容纳m个人,每种课程上课时间为ai~bi,上课人数为si,如果第i种课程上完后该教室要用于上第j种课程,需要clean[i][j]的时间进行打扫,问最少申请多少间教室。
.
.
解法:网络流。如果i上完后可以上j,那么i,j之间可以连一条边,我们考虑把每种课程拆分成两个点i和i+n,每种课程需要的教室成need[i],那么可以建图(s,i),(i+n,s)的流量为need[i],如果i后面可以上j的,那么(i, j+n)之间建一条流量为need[i]的边,那么跑出来的最大流代表可以共用的教室数量。
.
.

#include <stdio.h>#include <stdlib.h>#include <iostream>#include <string.h>#include <math.h>#include <iostream>using namespace std;const int maxlongint=1 << 31 -1;int i,j,k,n,m,tot,ans,s,t;int a[500001],b[500001],nextt[500001];int f[200][4];int last[505],x[505],y[505],r[505],w[505],count[505],cur[505],fa[505],dist[505],dat[505];int insert(int x, int y, int z){     tot++;     a[tot]=y;     b[tot]=z;     nextt[tot]=last[x];     last[x]=tot;     tot++;     a[tot]=x;     b[tot]=0;     nextt[tot]=last[y];     last[y]=tot;}int min(int x,int y){     if (x<y) return x ;     else return y;}int sap(int s, int t){     int i,j,k,x,p,sum;     count[0]=1;     count[1]=t-1;     for (i=1; i<=t-1; i++) dist[i]=1;     dist[t]=0;     for (i=1; i<=t; i++)     {          cur[i]=last[i];          fa[i]=0;          dat[i]=0;     }     dat[s]=maxlongint;     x=s; sum=0;     while (1)     {          k=cur[x];          while (k>0)          {               if ((b[k]>0)&&(dist[a[k]]==dist[x]-1)) break;               k=nextt[k];          }          if (k>0)          {               cur[x]=k;               fa[a[k]]=k;               dat[a[k]]=min(dat[x],b[k]);               x=a[k];               if (x==t)               {                    sum=sum+dat[x];                    while (x!=s)                    {                         b[fa[x]]=b[fa[x]]-dat[t];                         b[fa[x] xor 1]=b[fa[x] xor 1]+dat[t];                         x=a[fa[x] xor 1];                    }               }          }          else          {               count[dist[x]]--;               if (count[dist[x]]==0) return sum;               k=last[x];               dist[x]=t+1;               while (k!=0)               {                    if ((b[k]>0)&&(dist[a[k]]+1<dist[x]))                    {                         dist[x]=dist[a[k]]+1;                         cur[x]=k;                    }                    k=nextt[k];               }               count[dist[x]]++;               if (dist[s]>t) return sum;               if (x!=s) x=a[fa[x] xor 1];          }     }}int main() {     int tt;     cin >> tt;     for (int cases = 1; cases <= tt; cases++) {         memset(last, 0, sizeof(last));         tot = 1;         cin >> n >> m;         int t, sum = 0;         cout << "Case " << cases << ": ";         for (int i = 1; i <= n; i++) {             cin >> f[i][1] >> f[i][2] >> f[i][3];             t = f[i][3]/m;             if (f[i][3]%m > 0) t++;             f[i][3] = t;             f[i][0] = i;             sum = sum+f[i][3];         }         for (int i = 1; i <= n; i++)              for (int j = 1; j <= n; j++) {                 cin >> t;                 if (f[i][2]+t < f[j][1])                     insert(i+1, j+n+1, f[i][3]);             }        for (int i = 1; i <= n; i++) {            insert(0+1, i+1, f[i][3]);            insert(i+n+1, n+n+1+1, f[i][3]);        }        cout << sum-sap(1, n+n+1+1) << endl;     }}
0 0
原创粉丝点击