UVALive 3231 Fair Share

Fair Share

Time Limit: 3000ms
Memory Limit: 131072KB
This problem will be judged on  UVALive. Original ID: 3231
64-bit integer IO format: %lld      Java class name: Main
 

You are given N processors and M jobs to be processed. Two processors are specified to each job. To process the job, the job should be allocated to and executed on one of the two processors for one unit of time. If K jobs are allocated to a processor, then it takes K units of time for the processor to complete the jobs. To complete all the jobs as early as possible, you should allocate the M jobs to the N processors as fair as possible. Precisely speaking, you should minimize the maximum number of jobs allocated to each processor over all processors. The quantity, minimum number of jobs, is called fair share.

 


For example, you are given 5 processors and 6 jobs. Each job can be allocated to one of the two processors as shown in the table below. Job 1 can be allocated to processors 1 or 2, and job 2 can be allocated to processors 2 or 3, etc. If you allocate job 1 to processor 1, job 2 to processor 2, job 3 to processor 3, job 4 to processor 4, job 5 to processor 5, and job 6 to processor 1, then you have at most two jobs allocated to each processor. Since there are more jobs than processors in this example, some processors necessarily have at least two jobs, and thus the fair share is two.

Given N processors, M jobs, and the sets of two processors to which the jobs can be allocated, you are to write a program that finds the fair share. Processors are numbered from 1 toN and jobs are numbered from 1 to M . It is assumed that the sets of two processors to which the jobs can be allocated are distinct over all jobs.

That is, if a job J1 can be allocated to processors P1 or P2, and a job J2 which is different from J1 can be allocated to processors P3 or P4, then {P1, P2}$ \ne${P3, P4}.

 

 

Input

The input consists of T test cases. The number of test cases T is given in the first line of the input file. Each test case begins with a line containing an integer N1$ \le$N$ \le$1, 000, that represents the number of processors in the test case. It is followed by a line containing an integer M1$ \le$M$ \le$10, 000, that represents the number of jobs. In the following M lines, K-th line contains two distinct integers representing processors to which job K can be allocated, 1$ \le$K$ \le$M. The integers given in a line are separated by a space. After that, the remaining test cases are listed in the same manner as the above.

 

 

Output

Print exactly one line for each test case. The line should contain the fair share for that test case.

The following shows sample input and output for three test cases.

 

 

Sample Input

3                                    
5                                    
6                                    
1 2 
2 3  
3 4  
4 5  
5 1  
1 3
3 
2 
3 2 
1 2 
6 
6 
1 2 
3 4 
4 6 
6 5 
5 3 
6 3

Sample Output

2  
1 
2

Source

 
解题:最大流 + 二分
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int INF = 0x3f3f3f3f;
 4 const int maxn = 20010;
 5 struct arc {
 6     int to,flow,next;
 7     arc(int x = 0,int y = 0,int z = -1) {
 8         to = x;
 9         flow = y;
10         next = z;
11     }
12 } e[1000010];
13 int head[maxn],d[maxn],cur[maxn],tot,S,T;
14 void add(int u,int v,int flow) {
15     e[tot] = arc(v,flow,head[u]);
16     head[u] = tot++;
17     e[tot] = arc(u,0,head[v]);
18     head[v] = tot++;
19 }
20 bool bfs(){
21     queue<int>q;
22     q.push(T);
23     memset(d,-1,sizeof d);
24     d[T] = 1;
25     while(!q.empty()){
26         int u = q.front();
27         q.pop();
28         for(int i = head[u]; ~i; i = e[i].next){
29             if(e[i^1].flow > 0 && d[e[i].to] == -1){
30                 d[e[i].to] = d[u] + 1;
31                 q.push(e[i].to);
32             }
33         }
34     }
35     return d[S] > -1;
36 }
37 int dfs(int u,int low){
38     if(u == T) return low;
39     int tmp = 0,a;
40     for(int &i = cur[u]; ~i; i = e[i].next){
41         if(e[i].flow > 0 && d[e[i].to]+1== d[u]&&(a=dfs(e[i].to,min(e[i].flow,low)))){
42             e[i].flow -= a;
43             low -= a;
44             e[i^1].flow += a;
45             tmp += a;
46             if(!low) break;
47         }
48     }
49     if(!tmp) d[u] = -1;
50     return tmp;
51 }
52 int dinic(){
53     int ret = 0;
54     while(bfs()){
55         memcpy(cur,head,sizeof head);
56         ret += dfs(S,INT_MAX);
57     }
58     return ret;
59 }
60 int u[maxn*10],v[maxn*10],n,m;
61 bool build(int mid) {
62     memset(head,-1,sizeof head);
63     tot = 0;
64     for(int i = 1; i <= n; ++i)
65         add(S,i,mid);
66     for(int i = 1; i <= m; ++i) {
67         add(n + i,T,1);
68         add(u[i],n+i,1);
69         add(v[i],n+i,1);
70     }
71     return dinic() >= m;
72 }
73 int main() {
74     int kase;
75     scanf("%d",&kase);
76     while(kase--) {
77         scanf("%d%d",&n,&m);
78         for(int i = 1; i <= m; ++i)
79             scanf("%d%d",u+i,v+i);
80         S = 0;
81         T = n + m + 2;
82         int low = 0,high = m,ret;
83         while(low <= high){
84             int mid = (low + high)>>1;
85             if(build(mid)){
86                 ret = mid;
87                 high = mid - 1;
88             }else low = mid + 1;
89         }
90         printf("%d\n",ret);
91     }
92     return 0;
93 }
View Code

 

转载于:https://www.cnblogs.com/crackpotisback/p/4703849.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值