$n \leq 40$个人玩$m \leq 10$台游戏机,每台游戏机一秒内只能一人玩,每人一秒内只能玩一台。每台游戏机有个价格,在规定总价格内可以把一部分游戏机复制一次,每台只能复制一次。给每个人对在每台游戏机上的需求时间,求一种方案使得所有玩游戏结束的时间尽量早。每个人每台游戏需求时间$\leq 2500$。

先不考虑复制。$R_i$表示人$i$玩游戏总时间,$C_j$表示机器$j$被玩总时间。可以发现答案的下界是$max(max(R_i),max(C_j))$,叫$T$。然后把人和机器建一个二分图,保证每个点的度数为$T$,就能在上面不停地做最大匹配,就可以把答案定为$T$。这里这么搞:左边$n$个人和$m$个假人,右边$m$台机器和$n$个假机器,假的东西用来补度数。然后,两边会连四种边:(1)真人真机器,连很多条边,边数为对应时间(其实可以连一条边记一个边权);(2)假人真机器,如果那个机器的度数不到$T$,那它肯定有一段空闲时间为$T-C_j$,这么多条边连向他对应的假人;(3)真人假机器,同(2);(4)假人假机器,这时假人和假机器的度数不到$T$,可以把真人真机器的图复制一遍把每个点度数补到$T$。把“连很多条边”搞成“连一条边,记个边权”,每次做完最大匹配后把所有边权减去匹配边中最小的那一个,然后把边权为0的边删掉。此时如果一条匹配边左右两边都是真人真机器,把这个操作记录下来,以此输出方案。

然后是钱的问题。当$T$为某个$C_j$时钱有用,此时若有钱就复制他,把机器的被玩时间均分成两份,使得$T$变小。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<set>
//#include<queue>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m,B;
int a[],t[][],R[],C[]; bool co[];
struct Node{int a,b,c,d;}ans[]; int lans=; struct BG
{
int mp[][],p[],q[],n; bool vis[];
void clear(int N) {n=N;}
bool Pei(int x)
{
vis[x]=;
for (int i=;i<=n;i++) if (mp[x][i] && !q[i])
{
p[x]=i; q[i]=x;
return ;
}
for (int i=;i<=n;i++) if (mp[x][i] && q[i] && !vis[q[i]] && Pei(q[i]))
{
p[x]=i; q[i]=x;
return ;
}
return ;
}
void pei(int x) {memset(vis,,sizeof(vis)); Pei(x);}
}g; int main()
{
n=qread(); m=qread(); B=qread();
for (int i=;i<=m;i++) a[i]=qread();
for (int i=,x;i<=n;i++)
{
x=qread();
for (int j=,u,v;j<=x;j++)
{
u=qread(); v=qread();
t[i][u]=v;
}
} for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
R[i]+=t[i][j],C[j]+=t[i][j];
int T=,maxr=;
for (int i=;i<=n;i++) maxr=max(maxr,R[i]);
for (int j=;j<=m;j++) T=max(T,C[j]); T=max(T,maxr);
while (B)
{
int id=;
for (int j=;j<=m;j++) if (T==C[j] && co[j]) {id=-; break;}
if (id==-) break;
for (int j=;j<=m;j++) if (T==C[j]) {id=j; break;}
if (!id) break;
if (a[id]>B) break; int tot=T>>;
for (int i=;i<=n;i++)
{
if (tot<t[i][id]) {t[i][id+m]=tot; t[i][id]-=tot; break;}
else {tot-=t[i][id]; t[i][id+m]=t[i][id]; t[i][id]=;}
} co[id]=; B-=a[id];
C[id]=; for (int i=;i<=n;i++) C[id]+=t[i][id];
C[id+m]=; for (int i=;i<=n;i++) C[id+m]+=t[i][id+m];
T=; for (int j=;j<=m;j++) T=max(T,C[j]); T=max(T,maxr);
} g.clear(n+m+m);
for (int i=;i<=n;i++)
for (int j=;j<=m+m;j++) if (t[i][j])
g.mp[i][j]=g.mp[j+n][i+m+m]=t[i][j];
for (int i=;i<=n;i++) if (R[i]<T) g.mp[i][i+m+m]=T-R[i];
for (int j=;j<=m+m;j++) if (C[j]<T) g.mp[j+n][j]=T-C[j]; printf("%d\n",T);
for (int j=;j<=m;j++) printf("%d",co[j]); puts("");
lans=;
for (int i=;i<=n+m+m;i++) g.pei(i);
while (T)
{
int tmp=0x3f3f3f3f;
for (int i=;i<=n+m+m;i++) tmp=min(tmp,g.mp[i][g.p[i]]);
for (int i=;i<=n;i++) if (g.p[i]<=m+m)
ans[++lans]=(Node){i,g.p[i]<=m?g.p[i]:g.p[i]-m,T-tmp,tmp};
for (int i=;i<=n+m+m;i++) g.mp[i][g.p[i]]-=tmp;
for (int i=;i<=n+m+m;i++) if (g.mp[i][g.p[i]]==) {g.q[g.p[i]]=; g.p[i]=; g.pei(i);}
T-=tmp;
} printf("%d\n",lans);
for (int i=;i<=lans;i++) printf("%d %d %d %d\n",ans[i].a,ans[i].b,ans[i].c,ans[i].d);
return ;
}

Codeforces737E. Tanya is 5!的更多相关文章

  1. CodeForces 518B. Tanya and Postcard

    B. Tanya and Postcard time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  2. codeforces 518B. Tanya and Postcard 解题报告

    题目链接:http://codeforces.com/problemset/problem/518/B 题目意思:给出字符串 s 和 t,如果 t 中有跟 s 完全相同的字母,数量等于或者多过 s,就 ...

  3. Codeforces Round #288 (Div. 2)D. Tanya and Password 欧拉通路

    D. Tanya and Password Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/508 ...

  4. CF Tanya and Postcard

    Tanya and Postcard time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  5. Codeforces Round #324 (Div. 2) B. Kolya and Tanya 快速幂

    B. Kolya and Tanya Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/584/pro ...

  6. CodeForces - 508D Tanya and Password(欧拉通路)

    Description While dad was at work, a little girl Tanya decided to play with dad characters. She has ...

  7. Codeforces Round #346 (Div. 2) C Tanya and Toys

    C. Tanya and Toys 题目链接http://codeforces.com/contest/659/problem/C Description In Berland recently a ...

  8. 2016NEFU集训第n+3场 G - Tanya and Toys

    Description In Berland recently a new collection of toys went on sale. This collection consists of 1 ...

  9. codeforce round#466(div.2) B. Our Tanya is Crying Out Loud

    B. Our Tanya is Crying Out Loud time limit per test1 second memory limit per test256 megabytes input ...

随机推荐

  1. gEdit - GTK+ 基础文本编辑器

    语法 gedit [--help] [--version] [文件名] [文件名] [文件名] 等等... 描述 gEdit 是一个 X窗口系统下的基础文本编辑器由 GTK+ 写成.它现在支持建立,打 ...

  2. 【算法基础】欧几里得gcd求最大公约数

    package Basic; import java.util.Scanner; public class Gcd { public static void main(String[] args) { ...

  3. 如何在vue项目中使用sass(scss)

    1.用npm/cnpm/yarn安装sass的依赖包 npm install --save-dev sass-loader npm install --save-dev node-sass 或者: y ...

  4. WINDOWS-基础:WINDOWS常用API

    1.窗口信息 //MS 为我们提供了打开特定桌面和枚举桌面窗口的函数. hDesk=OpenDesktop(lpszDesktop,,FALSE,DESKTOP_ENUMERATE); //打开我们默 ...

  5. javase(14)_java基础增强

    一.Eclipse的使用 1.在eclipse下Java程序的编写和run as,debug as,及java运行环境的配置. 2.快捷键的配置,常用快捷键: •内容提示:Alt + / •快速修复: ...

  6. CF-1099 D. Sum in the tree

    CF-1099 D. Sum in the tree 题意:结点序号为 1~n 的一个有根树,根序号为1,每个点有一个权值a[i], 然后定义一s[i]表示从根节点到 结点序号为i的结点的路途上所经过 ...

  7. (46)zabbix报警媒介:Jabber

    Jabber有第三方插件,能让Jabber用户和MSN.YahooMessager.ICQ等IM用户相互通讯.因为Google遵从Jabber协议,并且Google已经将Gtalk的服务器开放给了其它 ...

  8. docker参考文档

    docker 使用笔记 http://www.cnblogs.com/xguo/p/3829329.html docker数据存储 | 单线程 http://opjasee.com/2014/06/2 ...

  9. day23 03 组合的例子

    day23 03 组合的例子 一.用到组合的方式,编写一个圆环,并能够计算出它的周长和面积 from math import pi # 从内置函数里面导入pi # 先定义一个圆类 class Circ ...

  10. python--FTP 上传视频示例

    # 服务端 import json import socket import struct server = socket.socket() server.bind(('127.0.0.1',8001 ...