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
  • 相关阅读:
    mysql source命令可以导入比较大的文件
    开源 小程序
    React-Native项目在Android真机上调试
    react-native中长度单位换算
    webpack 去console
    微信H5移动端真机调试--vConsole
    记录
    盘点ES7、ES8、ES9、ES10新特性
    Mach-o可执行文件简述
    堆排序算法
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/5228981.html
Copyright © 2011-2022 走看看