记录编号 56482 评测结果 AAAAAAAAAA
题目名称 [HAOI 2010]工厂选址 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.749 s
提交时间 2013-03-30 14:28:52 内存使用 11.19 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. int m,n;//m个煤矿,n个备选厂址
  6. //n<=50,m<=50000
  7. int h0;//第一个电站的固定费用
  8. int b;//第一个电站的需煤量
  9. int a[50005]={0};//每个煤矿的年产量
  10. int h[55]={0};//第i个备选厂址的固定费用
  11. int c0[50005]={0};//第i个矿到第一个电厂的单位运费
  12. int c[50005][55]={0};//第i个矿运到第j个厂址的单位运费
  13. //注意:编号为1开始
  14. int ans;//最佳厂址
  15. long long lcost=0xffffffff;//最小花费
  16. void read(void){
  17. scanf("%d%d%d%d",&m,&b,&h0,&n);
  18. int i,j;
  19. for(i=1;i<=m;i++) scanf("%d",&a[i]);
  20. for(i=1;i<=n;i++) scanf("%d",&h[i]);
  21. for(i=1;i<=m;i++) scanf("%d",&c0[i]);
  22. for(j=1;j<=n;j++){
  23. for(i=1;i<=m;i++) scanf("%d",&c[i][j]);
  24. }
  25. }
  26. class PAIR{
  27. public:
  28. int num;//编号
  29. int sub;//差值
  30. };
  31. bool cmp(PAIR a,PAIR b){
  32. return a.sub>b.sub;
  33. }//去1的单价-去2的单价越小越好
  34. void relax(int x){//选取x厂,进行更新
  35. long long now=0;//现在的总费用
  36. long long carry=0;//总运费
  37. int coal=0;//一厂的煤
  38. now+=h[x];
  39. int i;
  40. PAIR s[50005]={0};//每个矿的编号和到两个厂的差值
  41. for(i=1;i<=m;i++){
  42. s[i].num=i;
  43. s[i].sub=c0[i]-c[i][x];
  44. carry+=a[i]*c0[i];//先全部运到一号厂
  45. coal+=a[i];
  46. }
  47. sort(s+1,s+1+m,cmp);
  48. i=1;
  49. while(1){
  50. if(coal-a[s[i].num]>=b){
  51. carry-=a[s[i].num]*c0[s[i].num];
  52. carry+=a[s[i].num]*c[s[i].num][x];
  53. coal-=a[s[i].num];
  54. //从一厂换到现在的厂
  55. }
  56. else{
  57. carry-=(coal-b)*c0[s[i].num];
  58. carry+=(coal-b)*c[s[i].num][x];
  59. coal=b;
  60. break;
  61. }
  62. i++;
  63. }
  64. now=carry+h[x]+h0;
  65. if(now<lcost){
  66. lcost=now;
  67. ans=x;
  68. }
  69. }
  70. int main(){
  71. freopen("factory1.in","r",stdin);
  72. freopen("factory1.out","w",stdout);
  73. read();
  74. for(int i=1;i<=n;i++) relax(i);
  75. printf("%d\n%lld\n",ans,lcost);
  76. return 0;
  77. }