寒假Day17-UVALive3231Fair Share(最大流+二分)
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 to N 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} ̸= {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 N, 1 ≤ N ≤ 1, 000, that represents the number of processors in the test case. It is followed by a line containing an integer M, 1 ≤ M ≤ 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 ≤ K ≤ 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.
样例:
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
思路:最大流+二分,不好写
AC代码:(dfs+bfs+dinic)

1 #include<string.h> 2 #include<iostream> 3 #include<stdio.h> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 #include<map> 8 #include<cmath> 9 using namespace std; 10 #define inf 0x3f3f3f3f 11 const int N=20020; 12 typedef long long ll; 13 14 int a[10020],b[10020],n,m,s,t,tot; 15 int head[N],dep[N],cur[N]; 16 17 struct node 18 { 19 // int u,v,flow; 20 int nextt,v,flow; 21 } e[100*N]; 22 23 void add(int u,int v,int flow)//v,u,0 24 { 25 tot++; 26 //nextt[tot]=head[u]; 27 e[tot].nextt=head[u]; 28 head[u]=tot; 29 // e[tot].u=u; 30 e[tot].v=v; 31 e[tot].flow=flow; 32 33 tot++; 34 // nextt[tot]=head[v]; 35 e[tot].nextt=head[v]; 36 head[v]=tot; 37 //e[tot].u=v; 38 e[tot].v=u; 39 e[tot].flow=0; 40 } 41 42 int dfs(int u,int flow) 43 { 44 if(u==t) 45 return flow; 46 // int used=0; 47 for(int& i=cur[u]; i!=-1; i=e[i].nextt) //注意这里的&符号,这样i增加的同时也能改变cur[u]的值,达到记录当前弧的目的 48 { 49 if ((dep[e[i].v]==dep[u]+1)&&e[i].flow!=0) 50 { 51 // int di=dfs(e[i].v,min(flow-used,e[i].flow)); 52 int di=dfs(e[i].v,min(flow,e[i].flow)); 53 if (di>0) 54 { 55 e[i].flow-=di; 56 e[i^1].flow+=di; 57 // used+=di; 58 // if(used==flow) 59 // break; 60 return di; 61 } 62 } 63 } 64 // if(used!=flow) 65 // dep[u]=-1; 66 // return used; 67 return 0; 68 } 69 70 int bfs() 71 { 72 queue<int>Q; 73 memset(dep,-1,sizeof(dep)); 74 dep[s]=1; 75 Q.push(s); 76 while(!Q.empty()) 77 { 78 int u=Q.front(); 79 Q.pop(); 80 for (int i=head[u]; i!=-1; i=e[i].nextt) 81 { 82 if ((dep[e[i].v]==-1)&&(e[i].flow>0)) 83 { 84 dep[e[i].v]=dep[u]+1; 85 Q.push(e[i].v); 86 } 87 } 88 } 89 if(dep[t]!=-1) 90 return 1; 91 return 0; 92 } 93 94 int dinic() 95 { 96 int sum=0; 97 while(bfs()) 98 { 99 for(int i=s; i<=t; i++) 100 cur[i]=head[i]; 101 while(int di=dfs(s,inf)) 102 sum+=di; 103 // while (dfs(s,inf)) 104 // sum+=dfs(s,inf); 105 } 106 return sum; 107 } 108 109 int main() 110 { 111 int tt; 112 scanf("%d",&tt); 113 while(tt--) 114 { 115 scanf("%d %d",&n,&m);//n处理器1000 m任务10000 116 for(int i=1; i<=m; i++) 117 scanf("%d %d",&a[i],&b[i]); 118 int l=0,r=inf,ans; 119 s=0,t=n+m+1; 120 while(l<=r) 121 { 122 tot=-1; 123 memset(head,-1,sizeof(head)); 124 int mid=(l+r)/2,M=0; 125 for(int i=1; i<=m; i++) 126 { 127 add(s,i,1); 128 add(i,a[i]+m,1); 129 add(i,b[i]+m,1); 130 } 131 for(int i=1; i<=n; i++) //处理器到汇点t 132 add(i+m,t,mid); 133 M+=dinic(); 134 if(M>=m) 135 r=mid-1,ans=mid; 136 else 137 l=mid+1; 138 } 139 printf("%d\n",ans); 140 } 141 return 0; 142 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」