BZOJ 1070

这是一道网络流的题。
巨大的坑点→→这个输入第一行顺序是m,n。太坑了,WA了多次。
tyvj一定说我WA,下了数据明明对的,,,一脸懵逼。
贡献一下数据

输入

5 12
42 54 53 58 31
17 86 59 15 84
48 25 5 53 39
44 5 87 62 76
53 97 9 19 10
27 16 10 68 92
99 93 15 57 84
22 84 62 100 35
67 45 14 28 72
5 1 47 49 4
91 32 27 10 40
100 23 28 15 65

输出

19.08


讲讲怎么做:这是一道网络流最小费用流。拆点是关键,首先取源点S想所有车连边,流量1费用0,然后将所有修车的m个人拆为n个点,即为他修倒数第几辆车,将车i与人j的k点连边,那么这条的费用就是k*a[i][j],流量为1,最后将所有人拆成的点与汇点T连边,跑最小费用最大流即可。

代码~~~:

/**************************************************************
    Problem: 1070
    User: fantasticwtl
    Language: C++
    Result: Accepted
    Time:1296 ms
    Memory:42484 kb
****************************************************************/

#include <cstdio>
#include <memory.h>//这个头文件类似cstring...
using namespace std;
int ans,n,m,w[2005][2005],d[500001],q[500001],pr[500001],a[2005][2005],qcn,cn;
bool ff[500005],f[2005][2005];
bool spfa ()
{
    memset(ff,0,sizeof(ff));memset(pr,0,sizeof(pr));memset(d,120,sizeof(d));
    ff[1]=1;q[1]=1;int h=0,t=1;d[1]=0;
    while(h<t){
        h++;
        for(int i=2;i<=cn;i++)
         if(f[q[h]][i]&&d[i]>d[q[h]]+w[q[h]][i]){
             d[i]=d[q[h]]+w[q[h]][i];
             pr[i]=q[h];
             if(!ff[i])q[++t]=i,ff[i]=1;
         }
         ff[q[h]]=0;
    }
    if(d[cn]>1000000000)return 0;
    ans+=d[cn];
    return 1;
}
int main ()
{
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);//读入部分
    cn=1;
    for(int i=1;i<=n;i++){
        f[1][++cn]=1;
    }
    qcn=cn;
    for(int i=1;i<=m;i++)
     for(int j=1;j<=n;j++){
         cn++;
         for(int k=2;k<=n+1;k++){
             f[k][cn]=1;f[cn][qcn+m*n+1]=1;
             w[k][cn]=j*a[k-1][i];
             w[cn][k]=-w[k][cn];
         }
     }//建图部分
    cn++;
    while(spfa ()){//最小费用最大流
        int k=cn;
        while(k!=1)f[pr[k]][k]-=1,f[k][pr[k]]+=1,k=pr[k];
    }
    double ss=1.0*ans/n;//求平均等待时间
    printf("%.2lf\n",ss);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值