BZOJ 1070: [SCOI2007]修车(最小费用最大流)

建图很神奇..建完图其实就是裸的费用流了..

--------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#include<vector>

#include<queue>

#define rep(i,n) for(int i=0;i<n;++i)

#define clr(x,c) memset(x,c,sizeof(x))

#define Rep(i,l,r) for(int i=l;i<=r;++i)

using namespace std;

const int inf=0x3f3f3f3f;

const int maxn=602+5;

struct Edge {

int from,to,cap,flow,cost;

Edge(int u,int v,int c,int f,int w):

from(u),to(v),cap(c),flow(f),cost(w) {}

};

struct mcmf {

int d[maxn];

int p[maxn];

int a[maxn];

bool inq[maxn];

int n,s,t;

vector<int> g[maxn];

vector<Edge> edges;

void init(int n) {

this->n=n;

rep(i,n) g[i].clear();

edges.clear();

}

void addEdge(int u,int v,int c,int w) {

edges.push_back( Edge(u,v,c,0,w) );

edges.push_back( Edge(v,u,0,0,-w) );

g[u].push_back(edges.size()-2);

g[v].push_back(edges.size()-1);

}

bool spfa(int &flow,int &cost) {

clr(d,inf); clr(inq,0);

queue<int> q; q.push(s);

a[s]=inf; d[s]=0; inq[s]=1; p[s]=0;

while(!q.empty()) {

int x=q.front(); q.pop();

inq[x]=0;

rep(i,g[x].size()) {

Edge &e=edges[g[x][i]];

if(e.cap>e.flow && d[e.to]>d[x]+e.cost) {

d[e.to]=d[x]+e.cost;

p[e.to]=g[x][i];

a[e.to]=min(a[x],e.cap-e.flow);

if(!inq[e.to]) { q.push(e.to); inq[e.to]=1; }

}

}

}

if(d[t]==inf) return false;

flow+=a[t];

cost+=a[t]*d[t];

int x=t;

while(x!=s) {

edges[p[x]].flow+=a[t];

edges[p[x]^1].flow-=a[t];

x=edges[p[x]].from;

}

return true;

}

int minCost(int s,int t) {

this->s=s; this->t=t;

int flow=0,cost=0;

while(spfa(flow,cost));

return cost;

}

} g;

int main()

{

// freopen("test.in","r",stdin);

// freopen("test.out","w",stdout);

int m,n;

scanf("%d%d",&m,&n);

int t=n*m;

int S=0,T=t+n+1;

g.init(T+1);

Rep(i,1,n)

rep(j,m) {

int w;

scanf("%d",&w);

Rep(k,1,n) g.addEdge(j*n+k,t+i,1,w*k);

}

Rep(i,1,n) g.addEdge(i+t,T,1,0);

Rep(i,1,t) g.addEdge(0,i,1,0);

printf("%.2lf\n",(double)g.minCost(S,T)/n);

return 0;

}

--------------------------------------------------------------

1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2762  Solved: 1099
[Submit][Status][Discuss]

Description

同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

Input

第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。

Output

最小平均等待时间,答案精确到小数点后2位。

Sample Input

2 2
3 2
1 4

Sample Output

1.50

HINT

数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)

时间: 2024-07-30 16:23:04

BZOJ 1070: [SCOI2007]修车(最小费用最大流)的相关文章

[BZOJ 1070] [SCOI2007] 修车 【费用流】

题目链接:BZOJ - 1070 题目分析 首先想到拆点,把每个技术人员拆成 n 个点,从某个技术人员拆出的第 i 个点,向某辆车连边,表示这是这个技术人员修的倒数第 i 辆车.那么这一次修车对整个答案的贡献就是,i * Time[j][k]. j 是车的编号,k 是技术人员编号.因为这辆车以及之后这个人要修的车的等待时间都增加了 Time[j][k], 所以包括这辆车在内一共有 i 辆车的等待时间加上了这次修车的时间.这样倒着考虑就可以用边的费用很简便的表示修车使所有人增加的时间了.从 S 到

[BZOJ 1070][SCOI2007]修车(费用流)

Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Solution 非常经典的建图方式,将每一位技术人员拆成n个点分别他是表示倒数第几个修车的,倒数第k个修车的技术人员对所有在等待的人的贡献是tim[i][j]*k #include<iostream>

P2053 [SCOI2007]修车 最小费用最大流

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入输出格式 输入格式: 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式: 最小平均等待时间,答案精确到小数点后2位

BZOJ 1927 星际竞速(最小费用最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1927 题意:一个图,n个点.对于给出的每条边 u,v,w,表示u和v中编号小的那个到编号大的那个的时间为w.另外有n个值Ai,表示从任何一个点到达i点的时间为Ai.初始时你在n个点之外的一个 点上,我们称其为初始点B.要求从B出发,遍历n个点每个点一次,求最小时间.显然开始你只能使用Ai从B到达n个点中的某个点,因为B到n个点中没有其 他的边. 思路:因为最后停在了某个点上,那么从B出

bzoj 1070: [SCOI2007]修车 -- 费用流

1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MB Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第

BZOJ 2424: [HAOI2010]订货(最小费用最大流)

最小费用最大流..乱搞即可 ------------------------------------------------------------------------------ #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<queue> #define rep( i, n ) for( int i = 0; i <

BZOJ 1070 [SCOI2007]修车 最小费用流

题意:链接 方法:最小费用最大流 解析:前几天做的费用流,很经典,很神奇,很6的一道题,不过当时做完没时间写博客,所以今天给他传上来. 所以没看题解前我并没有做出来这道题,当时满脑子退?流?的思想啥都搞不出来. 看完题解后感觉好神奇! 假设n个人m辆车,那么每一个人都有一行状态,对应的是什么呢?是他倒数第几个修的是哪辆车,而这又是不确定的,所以我们还得将这个点连向m辆车,流量就是1,而费用呢就是倒数第几个乘以修理时间,原因呢?就是如果这个人倒数第几个修的这辆车的话,那么其他人都需要等他修完,所以

【BZOJ】1070: [SCOI2007]修车(费用流+特殊的技巧)

http://www.lydsy.com/JudgeOnline/problem.php?id=1070 好神的题!!!orz 首先我是sb不会拆点..... 首先,每一个技术人员维修车辆都有一个先后顺序,那么我们将技术人员每一次维修的顺序拆点!!即如果有n辆车,那么每个技术人员就拆成n个点向每个车子连边,容量为1,费用依次为k*时间,即表示如果第k次修这架车,那么这架车一定只等待了k*时间那么久.. 然后就行了.. (注意数据读入的顺序......没看清就会wa... #include <cs

bzoj 1070: [SCOI2007]修车

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define M 10000 5 #define inf 2139062143 6 using namespace std; 7 int cnt=1,n,m,T,d[M],q[2*M],f[M],head[M],next[10*M],u[10*M],v[10*M],w[10*M],fro[10*M],fr[M]; 8 int mp[100][10