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)

 

posted @ 2015-04-04 23:13  JSZX11556  阅读(173)  评论(0编辑  收藏  举报