[SCOI2007]修车(建图好题)

 [SCOI2007]修车

https://www.lydsy.com/JudgeOnline/problem.php?id=1070

Time Limit: 1 Sec  Memory Limit: 128 MB
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

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 */
View Code

 

posted on 2018-11-05 21:49  Fighting_sh  阅读(221)  评论(0编辑  收藏  举报

导航