bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110
[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
3 2
1 4
Sample Output
1.50
HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
╮(╯▽╰)╭学了那么久费用流,还是属于见到题根本想不到的情况啊。如果省选出这道题,那我不得哭死,一方面是想不到费用流,一方面是关于题目读入中n,m的输入顺序问题。
还记得不久前听说有人随便的一句话:网络流的题都能用贪心水过,当时只是笑笑罢了,咋遇到了“贪心”题就想不到用网络流水过呢?
只要想到是费用流,图什么的直接秒建,就不赘述了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 100000 #define MAXE MAXV*20 #define MAXV MAXN #define INF 0x3f3f3f3f struct Edge { int np,val,cost; Edge *next,*neg; }E[MAXE],*V[MAXV]; int sour=0,sink=1; int tope=-1; void addedge(int x,int y,int z,int c) { // cout<<"Add:"<<x<<" "<<y<<" "<<z<<" "<<c<<endl; E[++tope].np=y; E[tope].val=z; E[tope].cost=c; E[tope].next=V[x]; V[x]=&E[tope]; E[++tope].np=x; E[tope].val=0; E[tope].cost=-c; E[tope].next=V[y]; V[y]=&E[tope]; V[x]->neg=V[y]; V[y]->neg=V[x]; } int dis[MAXN]; int q[MAXN*20]; int vis[MAXN],vistime=0; int prv[MAXN]; Edge *prve[MAXN]; int spfa(int now) { int head=-1,tail=0; Edge *ne; memset(dis,INF,sizeof(dis)); dis[now]=0; q[0]=now; vis[now]=++vistime; while (head<tail) { now=q[++head]; vis[now]=0; for (ne=V[now];ne;ne=ne->next) { if (ne->val && dis[ne->np]>dis[now]+ne->cost) { dis[ne->np]=dis[now]+ne->cost; prv[ne->np]=now; prve[ne->np]=ne; if (vis[ne->np]!=vistime) q[++tail]=ne->np; } } } return dis[sink]!=INF; } pair<int,int> cost_flow() { pair<int,int> res; while (spfa(sour)) { int mxflow=INF; for (int x=sink;x!=sour;x=prv[x]) mxflow=min(mxflow,prve[x]->val); for (int x=sink;x!=sour;x=prv[x]) prve[x]->val-=mxflow,prve[x]->neg->val+=mxflow; res.first+=mxflow; res.second+=mxflow*dis[sink]; } return res; } int main() { freopen("input.txt","r",stdin); int n,m; scanf("%d%d",&m,&n); int x,y,z; for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) { scanf("%d",&x); for (int k=1;k<=n;k++) addedge(2+i,2+n+j*n+k,1,x*k); } } for (int i=1;i<=n;i++) addedge(sour,2+i,1,0); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) addedge(2+n+i*n+j,sink,1,0); printf("%.2lf\n",(double)cost_flow().second/n); }
by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载
本博客已停用,新博客地址:http://mhy12345.xyz