[SCOI2007]修车(建图好题)
[SCOI2007]修车
https://www.lydsy.com/JudgeOnline/problem.php?id=1070
Submit: 7306 Solved: 3108
[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个点,第k个点表示这个工人倒数第k个修车i,那么每辆车向工人连一条容量为1,费用为k*c,
表示修自己的车的一个费用,和后面k-1个人等待的费用,就是算自己费用的同时算上别人的费用。
1 #include<iostream> 2 #include<algorithm> 3 #include<queue> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 8 const int INF=0x3f3f3f3f; 9 const int N=50005; 10 const int M=500005; 11 int top; 12 int dist[N],pre[N]; 13 bool vis[N]; 14 int c[N]; 15 int maxflow; 16 17 struct Vertex{ 18 int first; 19 }V[N]; 20 struct Edge{ 21 int v,next; 22 int cap,flow,cost; 23 }E[M]; 24 25 void init(){ 26 memset(V,-1,sizeof(V)); 27 top=0; 28 maxflow=0; 29 } 30 31 void add_edge(int u,int v,int c,int cost){ 32 E[top].v=v; 33 E[top].cap=c; 34 E[top].flow=0; 35 E[top].cost=cost; 36 E[top].next=V[u].first; 37 V[u].first=top++; 38 } 39 40 void add(int u,int v,int c,int cost){ 41 add_edge(u,v,c,cost); 42 add_edge(v,u,0,-cost); 43 } 44 45 bool SPFA(int s,int t,int n){ 46 int i,u,v; 47 queue<int>qu; 48 memset(vis,false,sizeof(vis)); 49 memset(c,0,sizeof(c)); 50 memset(pre,-1,sizeof(pre)); 51 for(i=1;i<=n;i++){ 52 dist[i]=INF; 53 } 54 vis[s]=true; 55 c[s]++; 56 dist[s]=0; 57 qu.push(s); 58 while(!qu.empty()){ 59 u=qu.front(); 60 qu.pop(); 61 vis[u]=false; 62 for(i=V[u].first;~i;i=E[i].next){ 63 v=E[i].v; 64 if(E[i].cap>E[i].flow&&dist[v]>dist[u]+E[i].cost){ 65 dist[v]=dist[u]+E[i].cost; 66 pre[v]=i; 67 if(!vis[v]){ 68 c[v]++; 69 qu.push(v); 70 vis[v]=true; 71 if(c[v]>n){ 72 return false; 73 } 74 } 75 } 76 } 77 } 78 if(dist[t]==INF){ 79 return false; 80 } 81 return true; 82 } 83 84 int MCMF(int s,int t,int n){ 85 int d; 86 int i,mincost; 87 mincost=0; 88 while(SPFA(s,t,n)){ 89 d=INF; 90 for(i=pre[t];~i;i=pre[E[i^1].v]){ 91 d=min(d,E[i].cap-E[i].flow); 92 } 93 maxflow+=d; 94 for(i=pre[t];~i;i=pre[E[i^1].v]){ 95 E[i].flow+=d; 96 E[i^1].flow-=d; 97 } 98 mincost+=dist[t]*d; 99 // cout<<dist[t]<<" "<<d<<endl; 100 } 101 return mincost; 102 } 103 104 int main(){ 105 int n,m; 106 int v,u,w,c; 107 int s,t; 108 scanf("%d %d",&m,&n); 109 s=0,t=m*n+n+1; 110 init(); 111 //s->people->car->t 112 for(int i=1;i<=n;i++){//车 113 for(int j=1;j<=m;j++){//人 114 scanf("%d",&c); 115 for(int k=1;k<=n;k++){ 116 add((j-1)*n+k,m*n+i,1,c*k); 117 } 118 } 119 } 120 for(int i=1;i<=m;i++){ 121 for(int j=1;j<=n;j++){ 122 add(s,n*(i-1)+j,1,0); 123 } 124 } 125 for(int i=1;i<=n;i++){ 126 add(m*n+i,t,1,0); 127 } 128 double ans=MCMF(s,t,n+m*n+2); 129 printf("%.2f\n",ans/n); 130 } 131 /* 132 2 2 133 3 2 134 1 4 135 136 2 3 137 1 2 3 138 4 5 6 139 */
posted on 2018-11-05 21:49 Fighting_sh 阅读(221) 评论(0) 编辑 收藏 举报