[bzoj1070][SCOI2007]修车_费用流
修车 bzoj-1070 SCOI-2007
题目大意:有m个人要修n台车,每个工人修不同的车的时间不同,问将所有的车都修完,最少需要花费的时间。
注释:$2\le m\le 9$,$1\le n \le 60$
想法:想起了那句话...(如果题面复杂,dp状态不可描述,一看数据范围发现才几百,那八成是网络流了),一般这句话都是对的,除了那次在CF上遇到的爆搜.. ...
关于这道题,网上有题解在边上做技巧(完全没明白这样的意义),我的做法时拆点。将每个点拆成n个,然后在这些被拆的点与车之间连边即可,保证每走一条边需要将之后的费用都统计进来。
具体地,将一个j工人拆成n个点,第k个点表示这个工人倒数第k个修车i,那么车i向工人j连一条容量为1,费用为k*w[i][j],表示修自己的车的一个费用,和后面k-1个人等待的费用,就是算自己费用的同时算上别人的费用。注意这样倒着考虑,每个车连的边就只对关于同一个工人但是在他后面修车的有影响。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
#define N 610
#define M 76010
#define INF 0x3f3f3f
long long ans;
struct node{
int x,y,co,next,cap;
}edge[M];
int head[N],dis[N],pre[N];
bool vis[N];
int l,m,n,t,s,w;
void add(int x,int y,int c,int z)
{
l++;
edge[l].x=x;edge[l].y=y;edge[l].co=z;edge[l].cap=c;
edge[l].next=head[x];
head[x]=l;
}
bool spfa()
{
queue<int> q;
for(int i=0;i<=t;i++) {dis[i]=INF;vis[i]=0;}
memset(pre,0,sizeof(pre));
vis[s]=1;dis[s]=0;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
vis[x]=0;
for (int i=head[x];i!=-1;i=edge[i].next)
{
int y=edge[i].y;
if (edge[i].cap && dis[x]+edge[i].co<dis[y])
{
pre[y]=i;
dis[y]=edge[i].co+dis[x];
if (!vis[y]) q.push(y), vis[y]=1;
}
}
}
if (dis[t]<INF) return 1; else return 0;
}
void minf()
{
int i=pre[t],cap=INF;
while(i)
{
cap=min(cap, edge[i].cap);
i=pre[edge[i].x];
}
i=pre[t];
while(i)
{
edge[i].cap-=cap;
edge[i^1].cap+=cap;
ans+=cap*edge[i].co;
i=pre[edge[i].x];
}
}
int main()
{
scanf("%d%d", &m, &n);
l=1;
memset(head,-1,sizeof head);
t=n+m*n+1;s=0;
for(int i=1;i<=n;i++)
{
add(s,i,1,0);
add(i,s,0,0);
for(int j=1;j<=m;j++)
{
scanf("%d", &w);
for(int k=1;k<=n;k++)
{
add(i, j*n+k, 1, k*w);
add(j*n+k, i, 0, -k*w);
}
}
}
for(int j=n+1;j<=m*n+n;j++)
{
add(j,t,1,0);
add(t,j,0,0);
}
ans=0;
while(spfa()) minf();
printf("%.2lf\n", (double)ans / n);
}
小结:记住一些题目的描述,有利于帮助我门迅速分析出切入点。
[bzoj1070][SCOI2007]修车_费用流的更多相关文章
- BZOJ_1070_[SCOI2007]修车_费用流
BZOJ_1070_[SCOI2007]修车_费用流 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间 ...
- bzoj1070: [SCOI2007]修车(费用流)
1070: [SCOI2007]修车 题目:传送门 题解: 一道挺简单的费用流吧...胡乱建模走起 贴个代码... #include<cstdio> #include<cstring ...
- 2018.10.13 bzoj1070: [SCOI2007]修车(费用流)
传送门 费用流经典题目. 自我感觉跟TheWindy′sThe Windy'sTheWindy′s很像. 利用费用提前计算的思想来建图就行了. 代码: #include<bits/stdc++. ...
- P2053 [SCOI2007]修车(费用流)
P2053 [SCOI2007]修车 顾客平均等待的最小时间$=$等待总时间$/n$ 考虑只有1个技术人员时,$n$辆车等待总时间 $A_1+(A_1+A_2)+(A_1+A_2+A_3)+...+\ ...
- 【BZOJ1070】修车(费用流)
题意:同一时刻有N位车主带着他们的爱车来到了汽车维修中心. 维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的. 现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待 ...
- 【洛谷2053】 [SCOI2007]修车(费用流)
传送门 洛谷 Solution 考虑把每一个修车工人拆成\(n\)个点,那么考虑令\(id(i,j)\)为第\(i\)个工人倒数第\(j\)次修车. 然后就可以直接跑费用流了!!! 代码实现 /* m ...
- BZOJ1070[SCOI2007]修车——最小费用最大流
题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待 ...
- [BZOJ 1070] [SCOI2007] 修车 【费用流】
题目链接:BZOJ - 1070 题目分析 首先想到拆点,把每个技术人员拆成 n 个点,从某个技术人员拆出的第 i 个点,向某辆车连边,表示这是这个技术人员修的倒数第 i 辆车.那么这一次修车对整个答 ...
- 【BZOJ】1070: [SCOI2007]修车(费用流+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1070 好神的题!!!orz 首先我是sb不会拆点..... 首先,每一个技术人员维修车辆都有一个先后 ...
随机推荐
- JFreeChart之堆叠柱形图(StackedBar)
JFreeChart之堆叠柱形图(StackedBar) JAVA JFreeChart 最近的项目使用有个功能需要使用到堆叠柱形图,看了项目以前的代码实现没有想要的结果.所以自己就先到官网下载了 D ...
- centos vi和vim用法
所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正 ...
- 洛谷 P2986 [USACO10MAR]Great Cow Gat…(树形dp+容斥原理)
P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat… 题目描述 Bessie is planning the annual Great Cow Gathering for c ...
- golang——(strings包)常用字符串操作函数
(1)func HasPrefix(s, prefix string) bool 判断字符串s是否有前缀字符串prefix: (2)func HasSuffix(s, suffix string) b ...
- kafka与zookeeper实战笔记
kafka命令 1.先启动zookeeper zkServer.cmd/zkServer.sh2.启动kafka[需要指定server.properties文件] kafka-server-start ...
- HDU 4474 Yet Another Multiple Problem BFS
题意:求m的倍数中不包含一些数码的最小倍数数码是多少.比如15 ,不包含0 1 3,答案是45. BFS过程:用b[]记录可用的数码.设一棵树,树根为-1.树根的孩子是所有可用的数码,孩子的孩子也是 ...
- xhtml1-strict.dtd
<!-- Extensible HTML version 1.0 Strict DTD This is the same as HTML 4 Strict except for changes ...
- MySQL学习笔记之右连接
MySQL的右连接 #右连接,以右表为基表 select course.stuid,course.stuname,sex,course,city from class1 right join cour ...
- 【C++】颜色的设置
1.改变整个控制台的颜色用 system("color 0A"); 其中color后面的0是背景色代号,A是前景色代号.各颜色代码如下: 0=黑色 1=蓝色 2=绿色 3=湖蓝色 ...
- (转)基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理
http://www.cnblogs.com/wuhuacong/p/4777720.html 在很多系统模块里面,我们可能都需要进行一定的数据交换处理,也就是数据的导入或者导出操作,这样的批量处理能 ...