[SCOI2007][bzoj1070] 修车 [费用流]
题面
思路
我们考虑某个工人修车的从前到后序列如下:
${W_1,W_2,W_3,...,W_n}$
那么,对于这n辆车的车主而言,他们等候的总时间为:
$\sum_{i=1}^{n}W_i\ast\left(n-i+1\right)=nW_1+\left(n-1\right)W_2+...+2W_{n-1}+W_n$
这一步很重要,因为经过这一步推导,我们发现:对于“把第i辆车让第j个人在“需要消耗k次时间”的那个个位置修”这一个决策,可以等同为进行一个费用为$T\left(i,j\right)\ast k$的决策
因此我们可以得到一个决策集合:决策$\left(i,j,k\right)=T\left(i,j\right)\ast k$表示“把第i辆车让第j个人在“需要消耗k次时间”的那个个位置修”
那实际上我们就是对于每个i选取一个这样的决策,同时这个决策的$\left(j,k\right)$不能相同
那就好办了,我们建立一个二分图,左边是n辆车,右边是n*m个上述状态的二元组$\left(j,k\right)$(可以证明$k\leq n$)
源点向车连边,而决策二元组向汇点连边,流量1费用0
中间的边(注意这是一个完全二分图)就是流量1费用$T\left(i,j\right)\ast k$的
跑最小费用最大流即可
Code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 1e9
#define id(i,j) (i-1)*n+j
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
int n,m,cnt=-1,ans,first[1010],dis[1010],vis[1010];
struct edge{
int to,next,w,cap;
}a[100010];
inline void add(int u,int v,int w,int cap){
a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt;
a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt;
}
bool spfa(int s,int t){
int q[5010],head=0,tail=1,u,v,w,i;
memset(dis,-1,sizeof(dis));memset(vis,0,sizeof(vis));
q[0]=t;vis[t]=1;dis[t]=0;
while(head<tail){
u=q[head++];vis[u]=0;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;w=a[i].w;
if(a[i^1].cap&&((dis[v]==-1)||(dis[v]>dis[u]-w))){
dis[v]=dis[u]-w;
if(!vis[v]) vis[v]=1,q[tail++]=v;
}
}
}
return ~dis[s];
}
int dfs(int u,int t,int limit){
if(u==t||!limit){vis[u]=1;return limit;}
int i,v,f,flow=0,w;vis[u]=1;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;w=a[i].w;
if(!vis[v]&&a[i].cap&&(dis[v]==dis[u]-w)){
if(!(f=dfs(v,t,min(limit,a[i].cap)))) continue;
a[i].cap-=f;a[i^1].cap+=f;
ans+=f*w;flow+=f;limit-=f;
if(!limit) return flow;
}
}
return flow;
}
int zkw(int s,int t){//zkw费用流
int re=0;
while(spfa(s,t)){
vis[t]=1;
while(vis[t]){
memset(vis,0,sizeof(vis));
re+=dfs(s,t,inf);
}
}
return re;
}
int main(){
memset(first,-1,sizeof(first));int i,j,k,t1;
m=read();n=read();
for(i=1;i<=n;i++) add(0,i,0,1);
for(i=1;i<=m;i++) for(j=1;j<=n;j++) add(n+id(i,j),n+n*m+1,0,1);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
t1=read();
for(k=1;k<=n;k++){
add(i,n+id(j,k),t1*k,1);
}
}
}
zkw(0,n+n*m+1);
printf("%.2lf",((double)ans)/((double)n));//注意输出保留两位小数
}
[SCOI2007][bzoj1070] 修车 [费用流]的更多相关文章
- LG2053/BZOJ1070 「SCOI2007」修车 费用流
问题描述 LG2053 BZOJ1070 题解 将\(m\)个修理工拆为\(n \times m\)个,将修理工和车辆看做二分图,连出一个完全二分图. 边流量为\(1\),费用为时间,费用流即可. \ ...
- [bzoj1070][SCOI2007]修车——费用流
题目大意: 传送门 题解: 本题和(POJ3686)[http://poj.org/problem?id=3686]一题一模一样,而且还是数据缩小以后的弱化版QAQ,<挑战程序设计竞赛>一 ...
- [BZOJ1070] [SCOI2007] 修车 (费用流 & 动态加边)
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使 ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- P2053 [SCOI2007]修车 费用流
$ \color{#0066ff}{ 题目描述 }$ 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M ...
- 【BZOJ 1070】[SCOI2007]修车 费用流
就是拆个点限制一下(两点一排一大片),这道题让我注意到了限制这个重要的词.我们跑网络流跑出来的图都是有一定意义的,一般这个意义就对应了问题的一种方案,一般情况下跑一个不知道对不对的方案是相对容易的我们 ...
- bzoj 1070 修车 —— 费用流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1070 需要考虑前面修的车对后面等待的车造成的时间增加: 其实可以从每个人修车的顺序考虑,如果 ...
- BZOJ 1070 修车(费用流)
如果能想到费用流,这道题就是显然了. 要求所有人的等待平均时间最小,也就是所有人的总等待时间最小. 每辆车只需要修一次,所以s连每辆车容量为1,费用为0的边. 现在需要把每个人拆成n个点,把车和每个人 ...
- 【BZOJ1070】[SCOI2007]修车 费用流
[BZOJ1070][SCOI2007]修车 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的. ...
随机推荐
- java设计模式——单例模式(三)
容器单例模式 之前学习Structs2,Spring框架时,经常会听到单例,多例.虽然这与单例模式不太一样,但是都很类似.在程序运行的时候,就加载所有的实例,然后用的时候直接取出 看下面代码: /** ...
- 在 Java 8 中避免 Null 检查
如何预防 Java 中著名的 NullPointerException 异常?这是每个 Java 初学者迟早会问到的关键问题之一.而且中级和高级程序员也在时时刻刻规避这个错误.其是迄今为止 Java ...
- AFN post的数据编码格式问题
想到写任何关于AFN的东西其实我是拒绝的,因为自己这也是第一次用,毕竟AFN现在是最为流行的网络框架了,害怕自己理解的有误,所以不敢造次! 先在这里大致讲解一下过程吧,后期发现了再更正(主要是想让看官 ...
- dijkstra算法优先队列
d[i] 是起点到 I 节点的最短距离 void Dijkstra(int s) { priority_queue<P, vector<P>, greater<P> &g ...
- 【dp】奶牛家谱 Cow Pedigrees
令人窒息的奶牛题 题目描述 农民约翰准备购买一群新奶牛. 在这个新的奶牛群中, 每一个母亲奶牛都生两个小奶牛.这些奶牛间的关系可以用二叉树来表示.这些二叉树总共有N个节点(3 <= N < ...
- ABAP读取长文本的方法
SAP中所有的项目文本都存在以下两张数据表中: 1. STXH 抬头项目文本 透明表 2. STXL 明细项目文本 透明表 长文本读取方法 首先在STXH和STXL中根据OBJECT NAME ...
- mysql 5.7 编译安装脚本。
此脚本尽量运行在centos 服务器上面,用于编译安装mysql 5.7 将此脚本和相应的软件 都放到/usr/local/src 目录下面 由于不能上传附件 所以需要把cmake-3.9.6.ta ...
- python基础 字典排序
stus = [ {"name":"zhang","age":18}, {"name":"lisi" ...
- ubuntu16.04更换镜像源
1.备份原有 cp /etc/apt/sources.list /etc/apt/sources.list.old 2.打开阿里巴巴镜像源: https://opsx.alibaba.com/mir ...
- linux中搭建公网ftp服务器
Linux搭建ftp服务器汇总整理 一.检查linux中是否已经安装vsftpd服务端软件 rpm -qa |grep vsftpd 二.卸载linux中的vsftpd服务端软件 rpm -e vsf ...