[bzoj1070] 修车
这周学习了费用流,就写了几题。其中有一题就是bzoj上的修车,看起来很丧,交了6次都是除了样例全wa(事实证明样例说明不了什么,还会误导你……)。
题目大意:有m个技术人员n辆车,一个技术人员只能同时修一辆车,每个技术人员修某一辆车都有特定的时间。求最小的等待时间。
思路分析:这是一道费用流的题目,不看算法基本想不到是费用流。
那么问题来了:怎么建图!看这个题目就像是把技术人员拆点。按题意建图的话,边权不是确定的,所以考虑拆成倒数第一次,倒数第二次……的n个结点。
这样边权只要设为(之后的车数+1,也就是倒数的次数)*修车时间,因为包括自己之后每辆车都要等这么多时间。
然后跑一边费用流。
注意到它是二分图,所以可以用更高效的算法求解。而我比较蒻,只打了最简单的spfa。
注意事项:我连wa了6次,是因为我没有认真看题,而样例m=n,n和m读反了就挂了3次(感谢falldream学长帮我debug)!!后面3次是没仔细调完就交还是wa。
下面附上代码:
1 #include<cstdio> 2 using namespace std; 3 const int inf=2147483647; 4 int n,m,tot=1,mx,q[1010],d[1010],pree[1010],h[1010]; 5 struct edge{int to,nxt,cst,cap;}e[400010]; 6 bool vis[1010]; 7 int mn(int x,int y){return x>y?y:x;} 8 void add(int fr,int to,int cst,int cap) 9 { 10 e[++tot]={to,h[fr],cst,cap};h[fr]=tot; 11 e[++tot]={fr,h[to],-cst,0};h[to]=tot; 12 } 13 void init() 14 { 15 scanf("%d%d",&m,&n); 16 int a[10][61]; 17 for(int i=1;i<=n;i++) 18 for(int j=1;j<=m;j++) 19 scanf("%d",&a[j][i]); 20 for(int j=1;j<=n;j++) 21 { 22 for(int i=1;i<=m;i++) 23 { 24 for(int k=1;k<=n;k++) 25 add(j,i*n+k,a[i][j]*k,1);//从车向技术人员倒数第k辆连容量1费用k*修车费的边 26 add(i*n+j,n*m+n+1,0,1);//从技术人员修的每辆车连向汇点容量1费用0的边 27 } 28 add(0,j,0,1);//从源点连向每辆车容量1费用0的边 29 } 30 mx=n;n=n*m+n+1; 31 } 32 bool spfa() 33 { 34 for(int i=1;i<=n;i++)d[i]=inf; 35 int l=0,r=1;q[1]=0;vis[0]=1; 36 while(l!=r) 37 { 38 int x=q[l=l==n?0:l+1]; 39 for(int i=h[x];i;i=e[i].nxt) 40 if(e[i].cap&&e[i].cst+d[x]<d[e[i].to]) 41 { 42 int v=e[i].to; 43 pree[v]=i; 44 d[v]=d[x]+e[i].cst; 45 if(!vis[v]) 46 { 47 if(d[v]>d[l+1])q[r=r==n?0:r+1]=v; 48 else q[l]=v,l=l==0?n:l-1; 49 vis[v]=1; 50 } 51 } 52 vis[x]=0; 53 } 54 return d[n]==inf?0:1; 55 } 56 float cf() 57 { 58 int cost=0,mm=0; 59 while(spfa()) 60 { 61 int mi=inf; 62 for(int i=n;i;i=e[pree[i]^1].to) 63 mi=mn(mi,e[pree[i]].cap); 64 for(int i=n;i;i=e[pree[i]^1].to) 65 { 66 int ee=pree[i]; 67 e[ee].cap-=mi; 68 e[ee^1].cap+=mi; 69 } 70 cost+=d[n]*mi; 71 mm+=mi; 72 } 73 return mm==mx?cost:0; 74 } 75 int main() 76 { 77 init(); 78 printf("%.2f",cf()/mx); 79 return 0; 80 }
本文由qrc出品,若不在本博客上看到,请与本人联系。
网址:http://www.cnblogs.com/qrcer