zoukankan      html  css  js  c++  java
  • BZOJ2879 [Noi2012]美食节

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2879

    这题codevs上也有,不过数据不同:http://codevs.cn/problem/1935/

    如果你觉得你的程序跑得很快,那么你可以交codevs,如果你觉得你的程序可能是错的,那么请你交BZOJ

    BZOJ数据貌似厉害一些?不过BZOJ时限也放得开些。

    这题就是上题的升级版,在修车的基础上,数据很大,所以需要通过动态加边来使其变快。

    因为上题也分析到了,只有厨师走完短的路,才会走长的,那么如果没走短的路,我长的路留在这里只是增加spfa的复杂度。

    然后动态加边就可以了。

    这个题刚开始的思路是错的,就是我在动态加边的同时,可以动态加点,但这样需要一个数组记下这是哪个厨师,也要记下这是厨师的第几个菜。

    但是发现如果我的费用流需要退流的话,我记录第几个菜的数组需要-1,但是我做不到,这会导致这个点被重复算几次,然后就比答案小了。

    所以必须确定下位置,这样的话,你就不会重复的添加点了,最多重复添加相同意义的边,而因为流量限制,这条边没有实际意义。

    不过这样的话,速度就会变慢...

    好慢啊好慢啊...

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn=50;
    const int maxm=110;
    const int maxp=100010;
    const int INF=0x3f3f3f3f;
    
    struct Node{
        int data,next,low,cost;
    }node[maxp*maxn*2];
    
    #define now node[point].data
    #define www node[point].low
    #define ccc node[point].cost
    #define then node[point].next
    
    int n,m,cnt,ans;
    int s,t,Idex,tot;
    int head[maxp];
    int c[maxp],ind[maxp],ink[maxp];
    int dis[maxp],pre[maxp];
    int a[maxm][maxm];
    bool inq[maxp];
    deque<int >q;
    
    void add(int u,int v,int w,int c){
        node[cnt].data=v;node[cnt].next=head[u];node[cnt].low=w;node[cnt].cost=c;head[u]=cnt++;
        node[cnt].data=u;node[cnt].next=head[v];node[cnt].low=0;node[cnt].cost=-c;head[v]=cnt++;
    }
    
    bool SPFA(){
        int x,Low=INF,ta,tb;
        memset(dis,0x3f,sizeof(dis));
        q.push_back(s);dis[s]=0;pre[s]=pre[t]=-1;
        while(!q.empty()){
            x=q.front();q.pop_front();inq[x]=false;
            for(int point=head[x];point!=-1;point=then)
                if(www && dis[now]>dis[x]+ccc){
                    dis[now]=dis[x]+ccc;pre[now]=point^1;
                    if(!inq[now]){
                        inq[now]=true;
                        if(q.empty() || dis[q.front()]>dis[now])
                            q.push_front(now);
                        else
                            q.push_back(now);
                    }
                }
        }
        if(pre[t]<0) return false;
        for(int point=pre[t];point!=-1;point=pre[now]){
            if(now==s){
                x=node[point^1].data;
                ta=(x-1)/tot+1;tb=x%tot+1;
            }
            Low=min(Low,min(Low,node[point^1].low));
        }
        for(int point=pre[t];point!=-1;point=pre[now])
            node[point^1].low-=Low,www+=Low;
        for(int i=1;i<=m;i++)
            add((ta-1)*tot+tb,n*tot+i,1,tb*a[ta][i]);
        ans+=Low*dis[t];
        return true;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("2879.in","r",stdin);
        freopen("2879.out","w",stdout);
    #endif
        scanf("%d%d",&m,&n);
        for(int i=1;i<=m;i++) scanf("%d",&c[i]),tot+=c[i];
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&a[j][i]);
        t=n*tot+m+1;
        for(int i=s;i<=t;i++) head[i]=-1;
        for(int i=1;i<=n*tot;i++) add(s,i,1,0);
        for(int i=1;i<=m;i++)
            add(n*tot+i,t,c[i],0);
        for(int i=1;i<=n;i++)
           for(int k=1;k<=m;k++)
              add((i-1)*tot+1,n*tot+k,1,a[i][k]);
        while(SPFA());
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    tile38 复制配置
    The Guardian’s Migration from MongoDB to PostgreSQL on Amazon RDS
    tile38 一款开源的geo 数据库
    sqler sql 转rest api 的docker 镜像构建(续)使用源码编译
    sqler sql 转rest api javascript 试用
    sqler sql 转rest api redis 接口使用
    sqler sql 转rest api 的docker image
    sqler sql 转rest api 的工具试用
    apache geode 试用
    benthos v1 的一些新功能
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/5228981.html
Copyright © 2011-2022 走看看