【LA2238 训练指南】固定分区内存管理 【二分图最佳完美匹配,费用流】
题意
早期的多程序操作系统常把所有的可用内存划分为一些大小固定的区域,不同的区域一般大小不同,而所有区域的大小之和为可用内存的大小。给定一些程序,操作系统需要给每个程序分配一个区域,使得他们可以同时执行。可是每个程序的运行时间可能和它所占有的内存区域大小有关,因此调度并不容易。
编程计算最优的内存分配策略,既给定m个区域的大小和n个程序在各种内存环境下的运行时间,找出一个调度方案,使得平均结束时刻尽量小。具体来说,你需要给每个程序分配一个区域,使得没有两个程序同时在同一个时间运行在同一个内存区域中,而所有程序分配的区域大小都不小于该程序的最低内存需求。程序对内存的需求不会超过最大内存块的大小。
分析
这个题最重要的是明白一个很重要的结论:在同一个内存中,第倒数第k个执行的程序对于该内存总结束时间的贡献为kT,T为该程序在该内存下的运行时间。
有了这个结论,建图就并不难了。
下面我们来构造二分图,X结点为n个程序,Y结点为n*m个位置,其中位置(j,p)表示第j个内存的倒数第p个执行的程序。每个结点X和Y结点(j,p)之间连一条边权为pTi,j的边,然后求最小权匹配就可以。
并不是每个匹配都对应一个合法方案,但是,最佳匹配一定是对应一个合法方案。
我下面用费用流写的代码并不能AC,等以后看看是不是能找到bug。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue> using namespace std;
const int maxn=+;
const int maxm=+;
const int INF=1e9;
struct MCMF{
int head[maxn],to[maxm],Next[maxm],from[maxm],flow[maxm],cap[maxm];
long long cost[maxm];
int n,m,s,t,sz;
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn]; void init(int n){
this->n=n;
sz=-;
memset(head,-,sizeof(head));
}
void AddEdge(int a,int b,int ca,long long co){
++sz;
to[sz]=b,from[sz]=a,Next[sz]=head[a],head[a]=sz;
flow[sz]=,cap[sz]=ca,cost[sz]=co;
++sz;
to[sz]=a,from[sz]=b,Next[sz]=head[b],head[b]=sz;
flow[sz]=ca,cap[sz]=ca,cost[sz]=-co;
}
bool BellmanFord(int s,int t,int &Flow,long long &Cost){
for(int i=;i<=n;i++)d[i]=INF;
memset(inq,,sizeof(inq));
d[s]=;inq[s]=;p[s]=-;a[s]=INF;
queue<int>Q;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();
inq[u]=;
for(int i=head[u];i!=-;i=Next[i]){
int v=to[i];
if(cap[i]>flow[i]&&d[v]>d[u]+cost[i]){
d[v]=d[u]+cost[i];
p[v]=i;
a[v]=min(a[u],cap[i]-flow[i]);
if(!inq[v]){
Q.push(v);
inq[v]=;
}
}
}
}
if(d[t]==INF)return false;
Flow+=a[t];
Cost+=(long long)d[t]*(long long)a[t];
int u=t; while(u!=s){
flow[p[u]]+=a[t];
flow[p[u]^]-=a[t];
u=from[p[u]];
}
return true;
} long long Mincost(int s,int t){
int Flow=;
long long Cost=;
while(BellmanFord(s,t,Flow,Cost));
return Cost;
}
}mcmf;
const int maxN=;
const int maxM=;
int n,m,kase;
int Size[maxM];
int p[maxN][maxN],tim[maxN][maxN],Time[maxN];
int main(){
kase=;
while(scanf("%d%d",&m,&n)!=EOF&&(n||m)){
if(kase){
printf("\n");
} ++kase;
for(int i=;i<=m;i++)
scanf("%d",&Size[i]);
for(int i=;i<=n;i++){
scanf("%d",&p[i][]);
for(int j=;j<=p[i][];j++){
scanf("%d%d",&p[i][j],&tim[i][j]);
}
}
mcmf.init(n+n*m+);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(p[i][]>Size[j])continue;
int T=INF;
for(int l=;l<=p[i][];l++){
if(p[i][l]<=Size[j]){
T=min(T,tim[i][l]);
}
}
for(int l=;l<=n;l++){
mcmf.AddEdge(i,j*n+l,,l*T);
}
}
}
for(int i=;i<=n;i++)
mcmf.AddEdge(,i,,);
for(int i=n+;i<=n*m+n;i++)
mcmf.AddEdge(i,n*m+n+,,);
long long res=mcmf.Mincost(,n*m+n+);
double ans=(double)res/n;
printf("Case %d\n",kase);
printf("Average turnaround time = %.2f\n",ans); int ANS[maxN][maxN],bel[maxN];
memset(ANS,-,sizeof(ANS));
memset(Time,,sizeof(Time));
for(int i=;i<=n;i++){
for(int j=mcmf.head[i];j!=-;j=mcmf.Next[j]){
if(j%)continue;
if(mcmf.cap[j]>mcmf.flow[j])continue;
int v=mcmf.to[j];
int a=v/n,b=v%n;
if(b==){
b=n;
a--;
}
ANS[a][b]=i;
bel[i]=a;
Time[i]=mcmf.cost[j]/b;
}
}
int F[maxN],T[maxN];
for(int i=;i<=m;i++){
int st=;
for(int j=n;j>=;j--){
if(ANS[i][j]!=-){
st=j;
break;
}
}
int all=;
for(int j=st;j>=;j--){
int x=ANS[i][j];
F[x]=all,T[x]=all+Time[x];
all=T[x];
}
} for(int i=;i<=n;i++){
printf("Program %d runs in region %d from %d to %d\n",i,bel[i],F[i],T[i]);
}
}
return ;
}
【LA2238 训练指南】固定分区内存管理 【二分图最佳完美匹配,费用流】的更多相关文章
- UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)
UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- UVa 11383 少林决胜(二分图最佳完美匹配)
https://vjudge.net/problem/UVA-11383 题意: 给定一个N×N矩阵,每个格子里都有一个正整数W(i,j).你的任务是给每行确定一个整数row(i),每列也确定一个整数 ...
- Ants(二分图最佳完美匹配)
Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6904 Accepted: 2164 Special Ju ...
- UVA - 1045 The Great Wall Game(二分图最佳完美匹配)
题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...
- 【LA4043 训练指南】蚂蚁 【二分图最佳完美匹配,费用流】
题意 给出n个白点和n个黑点的坐标,要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接一条线段. 分析 结点分黑白,很容易想到二分图.其中每个白点对应一个X结 ...
- ZOJ-3933 Team Formation (二分图最佳完美匹配)
题目大意:n个人,分为两个阵营.现在要组成由若干支队伍,每支队伍由两个人组成并且这两个人必须来自不同的阵营.同时,每个人都有m个厌恶的对象,并且厌恶是相互的.相互厌恶的人不能组成一支队伍.问最多能组成 ...
- UVa 1349 - Optimal Bus Route Design(二分图最佳完美匹配)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVALive 2238 Fixed Partition Memory Management 固定分区内存管理(KM算法,变形)
题意:目前有一部分可用内存,分为m个大小固定的区域.现有n个程序要执行,每个程序在不同大小的内存中运行所需的时间不同,要使运行完所有程序所耗时最少,问每个程序在哪块区域中从什么时间运行到什么时间,以及 ...
- UVALive 4043 Ants 蚂蚁(二分图最佳完美匹配,KM算法)
题意: 有n个蚂蚁n棵树,蚂蚁与树要配对,在配对成功的一对之间连一条线段,要求所有线段不能相交.按顺序输出蚂蚁所匹配的树. 思路: 这个题目真是技巧啊,不能用贪心来为每个蚂蚁选择最近的树,这样很可能是 ...
随机推荐
- goreman 多进程管理工具
Linux下多进程管理工具对开发和运维都很有用,常见的功能全面的主流工具主要有monit.supervisor.不过开发中使用则推荐轻量级小工具goreman 举个例子:coreos的etcd就是使用 ...
- angularJS控制器之间的相互通信方式、$broadcast、$emit、$on
在项目中,我们可能会很经常性的利用到控制器之间的相互通信,在angular中的控制器之间的相互通信有以下几种方式: 1)通过本地数据的存储localstorage,sessionstorage, 2) ...
- SAE部署Django1.6+MySQL
[解决]SAE部署Django1.6+MySQL 终于可以舒口气了,今天大部分时间都在搞这个,很是蛋疼,网上资料良莠不齐,我不信这个之前没人做过,但是他们确实分享的不够好. 废话不多说,还是记录一下今 ...
- bc显示小数点前的0
bc是强大而常用的计算工具.不过在除法运算时,如果得到的结果值小于1,得到的小数前面的0不存.本篇提供几个常用小数点前缺0的解决方法. [root@maqing ~]# bc bc Copyright ...
- java 检测代理IP是否准确
我这里提供2个方法都可以实现:第一个是createIPAddress()和convertStreamToString() import java.io.IOException; import java ...
- Linux学习笔记 - Shell 函数的使用
基本语法 funname () { action; return -)):如果不加,将以最后一条命令运行结果,作为返回值. } 示例1:定义并调用无返回值的函数 #!/bin/bash a= b= c ...
- python cx_Oracle模块的安装和使用
$wget http://download.oracle.com/otn/linux/instantclient/10204/basic-10.2.0.4.0-linux-x86_64.zip 3 ...
- 详解华为交换机iStack特性
iStack特性的产品支持 iStack也就是我们平时所说的“堆叠”,但是华为交换机的iStack功能与其他厂商的交换机堆叠功能相比又有许多不同.在最新的Sx700大系中,只有S2700.S3700. ...
- Mysql Docker Container Command
Hello, in my docker-compose file I have the following: db: image: mysql command: mysqld --character- ...
- 【框架】Spring和dubbox
分布式服务框架 dubbo/dubbox 入门示例 https://www.cnblogs.com/yjmyzz/p/dubbox-demo.html 初识Spring Boot框架 https:// ...