首页 > 其他分享 >Heidi and Library (hard) | CodeForces 802C最大流最小费用

Heidi and Library (hard) | CodeForces 802C最大流最小费用

时间:2022-10-21 20:57:19浏览次数:49  
标签:GCC 802C hard flow CodeForces edge pragma optimize dis

神仙题,想了两节ds课没想出来,跑到奇怪的犄角旮旯去了还是没法搞一个满意的模型

看了洛谷黑题啊..释然了

思路和细节在代码

// LUOGU_RID: 90857083
#include<bits/stdc++.h>
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize(2)
using namespace std;
const int maxn=100010;

bool vis[maxn];
int n,m,k,s,t,x,y,z,f,Pre[maxn],book[maxn],a[maxn],c[maxn],dis[maxn],pre[maxn],last[maxn],flow[maxn],maxflow,mincost;
//dis最小花费;pre每个点的前驱;last每个点的所连的前一条边;flow源点到此处的流量 
struct Edge{
    int to,next,flow,dis;//flow流量 dis花费 
}edge[maxn];
int head[maxn],num_edge; 
queue <int> q;


void add_edge(int from,int to,int flow,int dis)
{
    edge[++num_edge].next=head[from];edge[num_edge].to=to;edge[num_edge].flow=flow;edge[num_edge].dis=dis;head[from]=num_edge;
    // 反向边流量为0,费用为负数
    edge[++num_edge].next=head[to];edge[num_edge].to=from;edge[num_edge].flow=0;edge[num_edge].dis=-dis;head[to]=num_edge;
}

bool spfa(int s,int t)
{
    memset(dis,0x7f,sizeof(dis));
    memset(flow,0x7f,sizeof(flow));
    memset(vis,0,sizeof(vis));
    q.push(s); vis[s]=1; dis[s]=0; pre[t]=-1;
    
    while (!q.empty())
    {
        int now=q.front();
        q.pop();
        vis[now]=0;
        for (int i=head[now]; i!=-1; i=edge[i].next)
        {
            if (edge[i].flow>0 && dis[edge[i].to]>dis[now]+edge[i].dis)//正边 
            {
                dis[edge[i].to]=dis[now]+edge[i].dis;
                pre[edge[i].to]=now;
                last[edge[i].to]=i;
                flow[edge[i].to]=min(flow[now],edge[i].flow);//
                if (!vis[edge[i].to])
                {
                    vis[edge[i].to]=1;
                    q.push(edge[i].to);
                }
            }
        }
    }
    return pre[t]!=-1;
}

void MCMF()
{
    while (spfa(s,t))
    {
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s)
        {//从源点一直回溯到汇点 
            edge[last[now]].flow-=flow[t];//flow和dis容易搞混 
            edge[last[now]^1].flow+=flow[t];
            now=pre[now];
        }
    }
}

int main()
{
    //freopen("lys.in","r",stdin);
    memset(head,-1,sizeof(head)); num_edge=-1;//初始化 
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>c[i];
    
    s=0;t=2*n+1;
    for(int i=1;i<=n;i++){
        /*
         拆点,对每一天拆成in 和 out
         流量为1,费用为c[i]表示当天的书必买 
         这样就能起码保证一种方案,就是说最大流就可以保证了。
         因为要决策每一天买不买不好表示,emmm也不是不行但可能
         需要用很复杂的状态表示,活生生做成dp&flow是吧
         考虑补集最近真的见到很多次了,我也该记住了,哪怕再笨
         考虑先把所有都买了——然后考虑是否有方案能够减少花费 
        */
        add_edge(s,i,1,c[a[i]]);
        /*
        in -> out,表示当天就把这本书丢了or卖了 
        */
        add_edge(i,i+n,1,0);// 流量限制为1表示丢了or卖了,only one choice 
        add_edge(i+n,t,1,0);//丢了 
        /*
          表示当天买的这本书在下一次需要的前一天给卖了,
          这样第二天买入的时候等价于-c+c,mean while we save us; 
        */
        if(Pre[a[i]]) add_edge(i-1,Pre[a[i]]+n,1,-c[a[i]]);
        Pre[a[i]]=i;
        // 这玩意要边走边维护,刚才煞笔了唔 
        /*
         为了限制流量,当天流向下一天的为k-1本,还有一个位置留给第二天强制买
         咋保留?就上面辣个先卖了,再买, 
        */
        if(i!=n) add_edge(i,i+1,k-1,0);
    }
    MCMF();
    cout<<mincost;
    return 0;
}

 

标签:GCC,802C,hard,flow,CodeForces,edge,pragma,optimize,dis
From: https://www.cnblogs.com/liyishui2003/p/16814721.html

相关文章

  • Codeforces Round #760 E
    E.Singers'Tour我们显然可以推式子b[i]=a[i]+2a[i+1]+3a[i+1]....b[i+1]=na[i]+a[i+1]+2a[i+2]....这样b[i+1]-b[i]=-n*a[i]+(a[i]+a[i+1]+....+a[n])我们显然......
  • Educational Codeforces Round 83 (Rated for Div. 2) C. Adding Powers(进制转换)
    https://codeforces.com/contest/1312/problem/C题目大意:给定一个长度为n的数组a,在给定一个底数k。一开始数组元素全部都是0,我们每一个时间i可以选择一个下标下的数字......
  • Educational Codeforces Round 138 (Rated for Div. 2) ABC(二分)
    只能说这场的出题人不适合我食用,ABC都读了假题,离谱啊~A.CowardlyRooks题目大意:给定一个棋盘n*n的大小,左下角的顶点在(1,1);给定了棋盘格上的m个棋子坐标。这m个棋子......
  • 「题解」Codeforces 1730F Almost Sorted
    给定一个长度为\(n\)的置换\(p\),以及一个正整数\(k\).对于一个置换\(q\),要求对于所有满足\(1\leqi<j\leqn\)的\(i,j\),有以下不等式成立:\[p_{q_i}\leqp_{q_j}+......
  • Codeforces Round #762 (Div. 3) E
    E.MEXandIncrements我们一看数据n个数还要计算n+1一个mex显然不能暴力我们考虑后面的i可以由前面的贪心的做一次操作转移过来所以我们记录一个a数组放着多出来的......
  • Codeforces1695 D1.+D2 Tree Queries
    题意给一个n个点的无向图,其中有一个隐藏点X,可以进行一组询问S来确定S是n个节点中的哪个点。S包括k个询问节点。询问返回的值也为k个值,每个值为X点到每个询问节点的最短路......
  • Educational Codeforces Round 138 (Rated for Div. 2)
    比赛链接EducationalCodeforcesRound138(RatedforDiv.2)D.CountingArrays解题思路容斥原理显然\([1,1,\dots,1]\)是一组方案,直接求不好求解,考虑反面,对于......
  • Educational Codeforces Round 92 B
    B.ArrayWalk考虑dpdp[i][j]表示前i步我们撤销了j次状态转移:dp[i][j]=max{dp[i-1][j-1]+a[(i-1)-(j-1)2-1]}//我们撤销一位dp[i][j]=max{dp[i-1][j]+a[(i-1)-j2+1]}......
  • Codeforces Global Round 23-C
    C题目链接:https://codeforces.com/contest/1746/problem/C此题着实不难,就是看你自己能不能想到那种构造的方法。自己做的时候没有很好的思路,所以参考了官方的解析()。个人......
  • ShardingSphere的配置中心
    ShardingSphere的配置中心本篇文章源码基于4.0.1版本使用配置中心来管理配置文件非常方便灵活,实现配置信息的动态加载,ShardingSphere支持很多配置中心,包括Apollo、Zooke......