【YZOJ 1060】分配工作

Description

Zxc接到一个任务--拯救世界。好在他有N个粉丝,Zxc把世界分成N个部分,每个粉丝处理一个部分,最后他来收尾。已知每个粉丝处理每个部分所需的时间,求拯救世界的最短时间是多少。每个人同时开始,但是不能互相帮忙。也就是说每个粉丝只能处理一个部分,并且一定要处理一个。

Input Format

第一行一个整数N,表示Zxc粉丝的个数。接下来N行,每行N个整数。第i+1行,第j个数表示第i个粉丝第j个部分所需要的时间。

Output Format

一个整数,表示最少需要的时间。

Sample Input

3
1 10 100
10 4 3
4 3 1

Sample Output

3

Hint

20%的数据满足1<=N<=25;

100%的数据满足1<=N<=800且最少需要的时间不超过10^9。

分析:看到题目首先想到的是用匈牙利找完美匹配,但是还要求时间最少,因为每个人的工作是分开的,互不干扰,所以使时间最少就是让用时最多的人用的时间u最少,二分枚举一下答案判断是否可以找到完美匹配就行了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3
 4 int n, m, t[1000][1000];
 5 int vis[1000], from[1000];
 6 int to[1000000], nxt[1000000], first[1000], en;
 7
 8 int ins (int p1, int p2)
 9 {
10     en++;
11     to[en] = p2;
12     nxt[en] = first[p1];
13     first[p1] = en;
14 }
15
16 int draw (int lim)
17 {
18     memset (to, 0, sizeof (to));
19     memset (nxt, 0, sizeof (nxt));
20     memset (first, 0, sizeof (first));
21     en = 0;
22     for (int i = 1; i <= n; i++)
23         for (int j = 1; j <= n; j++)
24             if (t[i][j] <= lim) ins (i, j);
25 }
26
27 bool find (int a)
28 {
29
30     for (int e = first[a]; e; e = nxt[e])
31     {
32         if (!vis[to[e]])
33         {
34             vis[to[e]] = 1;
35             if (from[to[e]] == -1 || find (from[to[e]]))
36             {
37                 from[to[e]] = a;
38                 return true;
39             }
40         }
41     }
42     return false;
43 }
44
45 bool work ()
46 {
47     int ans = 0;
48     memset (from, -1, sizeof (from));
49     for (int i = 1; i <= n; i++)
50     {
51         memset (vis, 0, sizeof (vis));
52         ans += find (i);
53     }
54     return ans == n;
55 }
56
57 int run ()
58 {
59     int l = 1, r = m, mid;
60     while (l < r)
61     {
62         mid = (l + r) >> 1;
63         draw (mid);
64         if (work ()) r = mid;
65         else l = mid + 1;
66     }
67     return r;
68 }
69
70 int main ()
71 {
72     scanf ("%d", &n); m = 0;
73     for (int i = 1; i <= n; i++)
74         for (int j = 1; j <= n; j++)
75             scanf ("%d", &t[i][j]),
76             t[i][j] > m ? m = t[i][j] : 0;
77     printf ("%d", run ());
78 }

PS:看起来好像每次都会有很多边,实际上二分下去剩得不多,用邻接矩阵一共跑了17.772s,用邻接表只跑了3.93s。(n+e只用了1.285s,ORZORZ)

时间: 2024-10-18 08:26:16

【YZOJ 1060】分配工作的相关文章

分配工作时需要考虑的问题

文章试图总结作为一个技术管理者给下属进行工作分配时,需要从哪些方面考虑,以及需要注意的问题.实际上,也可以作为一个下属如何完成上级分配工作的一个指引.就像文章里说到的,我们在分配给别人任务的时候,别人也在分配任务给我们.我们在别人身上寻找某种特质的时候,别人也在我们身上寻找类似的东西. 一般情况下,管理者都会将工作安排给自己信任的人,因为对他的工作能力和工作态度都比较熟悉,能预估到他的工作情况,不会出现太大的意外,有更大的掌控,所以才偏向于自己熟悉的人. 那面对还没有建立起信任关系的人,应该如何

员工分配工作(深度优先)

题意:公司分配N项工作给N个员工,每个员工只能被分给1项工作,每个人处理工作的时间不同.求完成所有工作所需的最少时间. 输入:第一行输入整数N,代表N个员工,员工编号从1到N(1<=N<=10)   接下来输入一个N*N的二维矩阵task[N][N],其中task[i][j](0<=task[i][j]<=1000)代表第i项工作由j号员工完成所需的时间. 输出:输出一个整数,代表工作完成所有工作所需的最少时间. 样例: 输入: 610 11 12 11 9 1111 9 10 1

Ka的回溯编程练习 Part4|分配工作

设有A,B,C,D,E五人从事J1,J2,J3,J4,J5五项工作,每人只能从事一项,他们的效益如下. 每人选择五项工作中的一项,在各种选择的组合中,找到效益最高的的一种组合输出. 这个主要是细节了,没什么难度 1 #include<stdio.h> 2 int MansToJobs[6][6]={{0,0,0,0,0,0},{0,13,11,10,4,7},{0,13,10,10,8,5},{0,5,9,7,7,4},{0,15,12,10,11,5},{0,10,11,8,8,4}}; 3

XJOI夏令营501训练1——分配工作

传送门:QAQQAQ 题意:某公司有工作人员x1,x2,…,xn ,他们去做工作y1,y2,…,ym(n<=m) ,每个人都能做其中的几项工作,并且对每一项工作都有一个固定的效率.问能否找到一种合适的工作分配方案,使得总的效率最高.要求一个人只能参与一项工作,同时一项工作也必须由一个人独立完成.不要求所有的人都有工作. 思路:首先让我们明确二分图匹配算法和网络流的区别:二分图KM算法是网络流最小费用最大流中的特例,即KM算法必须满足每一个x点都被匹配才能运行,但两个算法的前提都是在最大匹配的情况

[问题贴]小白请教几个关于Java虚拟机内存分配策略的问题

最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望大家帮我回答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI Capitan Java环境: java version "1.8.0_92" Java(TM) SE Runtime Environment (build 1.8.0_92-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode

LVS三种工作方式八种算法

一.集群简介 什么是集群 计算机集群简称集群是一种计算机系统,它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作.在某种意义上,他们可以被看作是一台计算机.集群系统中的单个计算机通常称为节点,通常通过局域网连接,但也有其它的可能连接方式.集群计算机通常用来改进单个计算机的计算速度和/或可靠性.一般情况下集群计算机比单个计算机,比如工作站或超级计算机性能价格比要高得多. 集群就是一组独立的计算机,通过网络连接组合成一个组合来共同完一个任务 LVS在企业架构中的位置: 以上的

【转载】Ogre的内存分配策略

原文:Ogre的内存分配策略 读这个之前,强烈建议看一下Alexandrescu的modern c++的第一章关于policy技术的解释.应该是这哥们发明的,这里只是使用. 首先列出涉及到的头文件:(这几个头文件彼此之间相关性挺大的,应该一起看) 只在调试期使用: OgreMemoryTracker.h 这个头文件中定义了MemoryTracker这个类,用来测试和调试Ogre的内存分配系统的.能跟踪内存的分配.回收.泄漏和统计信息.Ogre使用者不需要关注. OgreAlignedAlloca

每天一道算法编程题(1)——网易笔试&quot;工程师工作安排“问题

首先理解题目意思:每个人只能做工作序号表里的一件工作且两个人不能同时做一件工作.AC思路:采用暴力枚举每种可能的分配方案,子问题的解决逐步向上解决了母问题,最终原问题得解. 标程作者:NotDeep(牛客网)链接:https://www.nowcoder.com/discuss/22696?type=6&order=0&pos=5&page=2 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 vector&

源码分析:Java对象的内存分配

Java对象的分配,根据其过程,将其分为快速分配和慢速分配两种形式,其中快速分配使用无锁的指针碰撞技术在新生代的Eden区上进行分配,而慢速分配根据堆的实现方式.GC的实现方式.代的实现方式不同而具有不同的分配调用层次. 下面就以bytecodeInterpreter解释器对于new指令的解释出发,分析实例对象的内存分配过程: 一.快速分配 1.实例的创建首先需要知道该类型是否被加载和正确解析,根据字节码所指定的CONSTANT_Class_info常量池索引,获取对象的类型信息并调用is_un