BZOJ 4842 Delight for a cat - 费用流

题目是吸引你点进来的,不过代码和这个题不多的区别,一个是没有输出方案,一个是读入的时候读入的n行两列,还有就是t1表示至多而不是至少。好像可以线性规划,我写的上下界,不再赘述。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<climits>
#define INF (LLONG_MAX/10)
#define gc getchar()
#define lint long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define N 310
#define M 6010
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
#define buildedge(u,v,f,c) add_edge(u,v,f,c),add_edge(v,u,0,-(c))//debug(u)sp,debug(v)sp,debug(f)sp,debug(c)ln
#define build_edge(u,v,L,R,c) buildedge(s,v,L,c),buildedge(u,t,L,c),buildedge(u,v,R-L,c)
using namespace std;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct edges{
    int from,to,pre,resf,cost;
}e[M];int h[N],etop,pre[N];
lint d[N];queue<int> q;bool inq[N];
inline int add_edge(int u,int v,int f,int c,int x=0)
{
//  debug(u)sp,debug(v)sp,debug(f)sp,debug(c)ln;
    return x=++etop,e[x].from=u,e[x].to=v,e[x].pre=h[u],h[u]=x,e[x].resf=f,e[x].cost=c,x;
}
inline int spfa(int s,int t,int &f,lint &c)
{
    memset(inq,false,sizeof(bool)*(t+1));
    for(int i=1;i<=t;i++) d[i]=-INF;
    memset(pre,0,sizeof(int)*(t+1));
    d[s]=0,q.push(s),inq[s]=true;
    while(!q.empty())
    {
        int x=q.front();q.pop(),inq[x]=false;
        for(int i=h[x],y;i;i=e[i].pre)
            if(e[i].resf&&d[y=e[i].to]<d[x]+e[i].cost)
            {
                d[y]=d[x]+e[i].cost,pre[y]=i;
                if(!inq[y]) inq[y]=true,q.push(y);
            }
    }
    if(!pre[t]) return false;int minf=INT_MAX; 
    for(int i=pre[t];i;i=pre[e[i].from])
        minf=min(minf,e[i].resf);
    for(int i=pre[t];i;i=pre[e[i].from])
        e[i].resf-=minf,e[((i-1)^1)+1].resf+=minf;
    return f+=minf,c+=minf*d[t],true;
}
inline lint max_flow(int s,int t)
{
    int flow=0;lint cost=0;while(spfa(s,t,flow,cost));return cost;
}
int A[N],B[N];
int main()
{
//  freopen("T1.in","r",stdin),freopen("T1.out","w",stdout);
    int n=inn(),k=inn(),L=k-inn(),R=inn(),s=n+2,t=s+1;lint ans=0ll;
//  debug(L)sp,debug(R)sp,debug(s)sp,debug(t)ln;
    for(int i=1;i<=n;i++) A[i]=inn(),B[i]=inn(),ans+=B[i];
    buildedge(s,1,k,0),buildedge(n+1,t,k,0);
    for(int i=1;i<k;i++) buildedge(i,i+1,k,0);
    for(int i=k;i<=n;i++) build_edge(i,i+1,L,R,0);
    for(int i=1;i<=n;i++)
        buildedge(i,min(n+1,i+k),1,A[i]-B[i]);
    return !printf("%lld\n",ans+max_flow(s,t));
}

猜你喜欢

转载自blog.csdn.net/mys_c_k/article/details/80807304