码迷,mamicode.com
首页 > 其他好文 > 详细

中国计量大学现代科技学院第四届“中竞杯”程序设计校赛 G 请问您要来点兔子吗?

时间:2020-12-22 11:54:15      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:BMI   i+1   ref   std   cost   不用   scan   amp   lock   

这题费用流,题解已经说得很好了,补充一下就是这题不用拆点,(虽然我拆点了),只要现在i到i+k的流量为1就能保证每个点只用一次了
[题目链接](https://ac.nowcoder.com/acm/contest/9680#submit/{"problemIdFilter"%3A214521%2C"statusTypeFilter"%3A5})

#include<bits/stdc++.h>
using namespace std;
#define maxn 1605
const int inf=1e9;
struct E
{
    int to,next,flow,cost;
}e[maxn*20];
int head[maxn],cnt,nex[maxn],pre[maxn];
int st,ed,n,m;
void addedge(int u,int v,int flow,int cost)
{
    e[cnt].to=v;
    e[cnt].flow=flow;
    e[cnt].cost=cost;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
int d[maxn];
void add(int u,int v,int flow,int cost)
{
    addedge(u,v,flow,cost);
    addedge(v,u,0,-cost);
}
void build(int u,int v,int l,int r,int cost)
{
    add(u,v,r-l,cost);
    d[u]-=l;d[v]+=l;
}
int a[maxn],vis[maxn],dis[maxn],flow[maxn];
queue<int>q;
int bfs()
{
    while(!q.empty()) q.pop();
    for(int i=0;i<=2*n+10;i++) dis[i]=-inf,flow[i]=inf,vis[i]=0;
    q.push(st);vis[st]=1;dis[st]=0;
    //printf("flow[%d]=%d\n",ed,flow[ed]);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        //printf("dis[%d]=%d\n",u,dis[u]);
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to,f=e[i].flow,cost=e[i].cost;
            //printf(" v=%d f=%d cost=%d\n",v,f,cost);
            //if(u==20)printf("dis[%d]=%d dis[%d]=%d\n",u,dis[u],v,dis[v]);
            if((f>0)&&dis[u]+cost>dis[v])
            {
                //printf(" -v=%d f=%d cost=%d\n",v,f,cost);
                dis[v]=dis[u]+cost;
                pre[v]=i;flow[v]=min(flow[u],f);
                if(vis[v]==0)
                {
                    vis[v]=1;q.push(v);
                }
            }
        }
        vis[u]=0;
    }
    //printf("flow[%d]=%d\n",ed,flow[ed]);
    return (flow[ed]==inf)?0:1;
}
void slove()
{
    //int ans=-1e9;
    int mxflow=0,mxcost=0;
    while(bfs())
    {
        mxflow+=flow[ed];
        mxcost+=flow[ed]*dis[ed];
        //ans=max(ans,mxcost);
        //printf("mxflow=%d mxcost=%d\n",mxflow,mxcost);
        int v=ed;
        //printf("--v=%d\n",v);
        while(1)
        {
           int u=e[pre[v]^1].to;
           e[pre[v]].flow-=flow[ed];
           e[pre[v]^1].flow+=flow[ed];
           v=u;
           //printf("--v=%d\n",v);
           if(v==st) break;
        }
    }
    printf("%d\n",mxcost);
}
void init()
{
    memset(d,0,sizeof(d));
    memset(head,-1,sizeof(head));
    cnt=0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        st=0,ed=2*n+1;int ex=2*n+2;
        int k,l,r;
        scanf("%d %d %d",&k,&l,&r);
        for(int i=1;i<=n;i++)
        {
            add(i,n+i,1,a[i]);
        }
        for(int i=1;i<n;i++)
        {
            if(i<k) add(i,i+1,inf,0);
            else add(i,i+1,r-l,0);
        }
        for(int i=1;i<=n;i++)
        {
            if(i+k<n+1)
            {
                add(n+i,i+k,1,0);
            }
            else
            {
                add(n+i,ex,1,0);
            }
        }

        add(n,ex,r-l,0);
        add(ex,ed,r,0);
        add(st,1,r,0);
        slove();
    }
}

中国计量大学现代科技学院第四届“中竞杯”程序设计校赛 G 请问您要来点兔子吗?

标签:BMI   i+1   ref   std   cost   不用   scan   amp   lock   

原文地址:https://www.cnblogs.com/League-of-cryer/p/14147173.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!