【UVALive 3231】Fair Share 最大流
来源:互联网 发布:javaweb高级编程目录 编辑:程序博客网 时间:2024/04/29 16:02
据说这个问题叫公平分配问题,把M个任务分配给N个处理器,每个任务有两个对应的处理器,可以任选一个处理器处理这个任务,要求所有的处理器中处理任务最多的处理任务尽量少。
Vjudge
题目,不难,一看就是二分时间,然后判断能否在时间之内完成任务,设置0为超级源,N+M+1为超级汇,然后从超级源到每个任务连接一个容量为1的弧,从每个任务连接一个容量为1的弧到处理器,然后从每个处理器到超级汇连接一个容量为MID的弧。然后用Dinic跑最大流。。。。
恩,还好大概一两个小时就打完了,还算满意。但是交上去TLE,于是我郁闷了。调试半天,看了一下刘汝佳的蓝书发现他的DINIC多了个cur数组。。奇奇怪怪的,不知道干嘛,他说避免重复计算。后来在我的代码加上这句话就AC了。
当前弧优化
这个数组cur【u】叫做当前需要搜索的弧的编号,在初始化的时候就是head【u】,但是在后面我一次一次搜索的时候因为我有一部分弧已经没塞满,在我后面搜索的时候就不用考虑,而直接从没有塞满的开始考虑,这是为什么呢?因为我DINIC是在层次图上一条一条的灌水,那么我编号变化只有一种情况就是上一条弧已经被塞满,所以我在循环的时候就可以不断更新cur数组,这样极大的优化了代码吧?反正一加这个就AC了。
代码:
#include <iostream>#include <cstring>#include <cstdio>#include <queue>const int MAXN = 20000;using namespace std;int T,N,M,e = 2,sum,ans;int cur[MAXN],head[MAXN],d[MAXN];queue<int>q;struct node{ int v,c,f,next;}edge[MAXN*100];struct node_A{ int A,B;}Ta[MAXN];inline int read(){ int x = 0;char ch = getchar(); while(ch < '0' || '9' < ch){ch = getchar();} while('0' <= ch&&ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x;}inline void addedge(int u,int v,int c,int f){ edge[e] = (node){v,c,f,head[u]};head[u] = e++; edge[e] = (node){u,0,f,head[v]};head[v] = e++;}inline void build(int MID){ memset(head,0,sizeof(head)); e = 2; for(int i = 1;i <= M;i++) //从超级源到每个任务 addedge(0,i,1,0); for(int i = 1;i <= M;i++) //从每个任务到对应处理器 addedge(i,Ta[i].A+M,1,0), addedge(i,Ta[i].B+M,1,0); for(int i = 1;i <= N;i++) //从每个处理器到超级汇 addedge(i+M,M+N+1,MID,0);}inline bool bfs(){ memset(d,0,sizeof(d)); q.push(0);d[0] = 1; while(!q.empty()){ int x = q.front();q.pop(); for(int i = head[x];i;i = edge[i].next){ int v = edge[i].v; if(!d[v] && edge[i].c > edge[i].f){ d[v] = d[x] + 1; q.push(v); } } } return d[M+N+1] ? true : false;}int Dinic(int x,int a){ if(x == N+M+1 || a == 0) return a; int flow = 0,f; for(int &i = cur[x];i;i = edge[i].next){ int v = edge[i].v,c = edge[i].c,f = edge[i].f; if(d[v] == d[x] + 1 && (f = Dinic(v,min(a,c-f)) > 0)){ edge[i].f += f; edge[i^1].f -= f; flow += f; a -= f; if(a == 0) break; } } return flow;}int main(){ T = read(); while(T--){ N = read();M = read(); //N是处理器 M是任务 for(int i = 1;i <= M;i++) Ta[i].A = read(),Ta[i].B = read(); int L = 1,R = M; ans = 0; while(L <= R) { int MID = (L + R) >> 1; sum = 0;build(MID); while(bfs()){ for(int i = 0;i <= N+M+1;i++) cur[i] = head[i]; sum += Dinic(0,100000); } if(sum >= M) R = MID - 1,ans = MID; else L = MID + 1; } printf("%d\n",ans); } return 0; }
0 0
- 【UVALive 3231】Fair Share 最大流
- UVALive 3231 Fair Share 最大流(公平分配)
- LA 3231 Fair Share 【二分+最大流】
- LA 3231 Fair Share(网络流 + 二分)
- 最大最小公平共享算法 Max-min Fair Share Algorithm
- FairScheduler源码计算fair share
- UVALIVE 4819 最大流
- UVALive 6557 Stampede!(最大流)
- UVALive 4957 Fake scoreboard 最大流
- Uvalive 4865 Data Recovery 最大流
- uvalive 2957 Bring Them There(最大流)
- UVALive 6851The Programmers(最大流)
- UVALive 3645 Objective: Berlin(最大流)
- UVALive 2531 The K-League 最大流
- UVALive 6555 Playing Fair with Cryptography(细节处理)
- Educational Codeforces Round 8 F. Bear and Fair Set(最大流 | Hall定理)
- Educational Codeforces Round 8 F. Bear and Fair Set【最大流】
- Educational Codeforces Round 8 F. Bear and Fair Set(最大流 | Hall定理)★
- Linux网络基本网络配置方法介绍
- 理解Redux
- zznu 2009: 咫尺之间
- 自定义圆形ImageView 实现思路 -- Android 学习之路
- 深入理解javascript原型和闭包(4)——隐式原型
- 【UVALive 3231】Fair Share 最大流
- Android_杂七乱八
- 闭包执行的时候值的传递方式
- 字符的全排列
- 特征值和特征向量
- Makefile学习笔记(一)
- Effective C++ 学习笔记(十)
- 书单
- C++面试中string类的一种正确写法