记录编号 |
56482 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HAOI 2010]工厂选址 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.749 s |
提交时间 |
2013-03-30 14:28:52 |
内存使用 |
11.19 MiB |
显示代码纯文本
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- int m,n;//m个煤矿,n个备选厂址
- //n<=50,m<=50000
- int h0;//第一个电站的固定费用
- int b;//第一个电站的需煤量
- int a[50005]={0};//每个煤矿的年产量
- int h[55]={0};//第i个备选厂址的固定费用
- int c0[50005]={0};//第i个矿到第一个电厂的单位运费
- int c[50005][55]={0};//第i个矿运到第j个厂址的单位运费
- //注意:编号为1开始
- int ans;//最佳厂址
- long long lcost=0xffffffff;//最小花费
- void read(void){
- scanf("%d%d%d%d",&m,&b,&h0,&n);
- int i,j;
- for(i=1;i<=m;i++) scanf("%d",&a[i]);
- for(i=1;i<=n;i++) scanf("%d",&h[i]);
- for(i=1;i<=m;i++) scanf("%d",&c0[i]);
- for(j=1;j<=n;j++){
- for(i=1;i<=m;i++) scanf("%d",&c[i][j]);
- }
- }
- class PAIR{
- public:
- int num;//编号
- int sub;//差值
- };
- bool cmp(PAIR a,PAIR b){
- return a.sub>b.sub;
- }//去1的单价-去2的单价越小越好
- void relax(int x){//选取x厂,进行更新
- long long now=0;//现在的总费用
- long long carry=0;//总运费
- int coal=0;//一厂的煤
- now+=h[x];
- int i;
- PAIR s[50005]={0};//每个矿的编号和到两个厂的差值
- for(i=1;i<=m;i++){
- s[i].num=i;
- s[i].sub=c0[i]-c[i][x];
- carry+=a[i]*c0[i];//先全部运到一号厂
- coal+=a[i];
- }
- sort(s+1,s+1+m,cmp);
- i=1;
- while(1){
- if(coal-a[s[i].num]>=b){
- carry-=a[s[i].num]*c0[s[i].num];
- carry+=a[s[i].num]*c[s[i].num][x];
- coal-=a[s[i].num];
- //从一厂换到现在的厂
- }
- else{
- carry-=(coal-b)*c0[s[i].num];
- carry+=(coal-b)*c[s[i].num][x];
- coal=b;
- break;
- }
- i++;
- }
- now=carry+h[x]+h0;
- if(now<lcost){
- lcost=now;
- ans=x;
- }
- }
- int main(){
- freopen("factory1.in","r",stdin);
- freopen("factory1.out","w",stdout);
- read();
- for(int i=1;i<=n;i++) relax(i);
- printf("%d\n%lld\n",ans,lcost);
- return 0;
- }