zoukankan      html  css  js  c++  java
  • CF802C Heidi and Library (hard)

    题意同https://www.luogu.org/problemnew/show/P4404,稍有改动

    连边方法感觉贼神仙想不到,每个流的意义是一个空的书架。

    每一天拆成两个点(A_i,B_i),连((S,A_i,1,c_{a_i}),(A_i,B_i,1,-inf),(B_i,T,1,0))

    然后对两天(i<j),如果(a_i=a_j),连((B_i,A_j,1,0)),否则连((B_i,A_j,1,c_{a_j})),表示书架的这个位置第(i)天用完了第(j)天再用(连向(T)代表不会再用了)

    总费用加上(n*inf)就是答案了(inf是用来保证一定流这条边的)

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il int gi(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int fir[170],dis[100010],nxt[100010],w[100010],id=1,S,T;
    ll cost[100010];
    il vd link(int a,int b,int c,ll d){
        nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c,cost[id]=d;
        nxt[++id]=fir[b],fir[b]=id,dis[id]=a,w[id]=0,cost[id]=-d;
    }
    il vd Mincost(ll&totalcost){
        static int que[170],hd,tl,lst[170];
        static ll dist[170];
        static bool inq[170];
        hd=tl=0;que[tl++]=S;inq[S]=1;
        for(int i=1;i<=T;++i)dist[i]=1e18;
        dist[S]=0;
        while(hd^tl){
            int x=que[hd];
            for(int i=fir[x];i;i=nxt[i])
                if(w[i]&&dist[dis[i]]>dist[x]+cost[i]){
                    dist[dis[i]]=dist[x]+cost[i],lst[dis[i]]=i;
                    if(!inq[dis[i]]){
                        inq[dis[i]]=1,que[tl++]=dis[i];
                        if(tl==110)tl=0;
                    }
                }
            inq[x]=0,++hd;
            if(hd==170)hd=0;
        }
        if(dist[T]>0)return;
        for(int i=lst[T];i;i=lst[dis[i^1]])totalcost+=cost[i],--w[i],++w[i^1];
    }
    int a[81],c[81];
    int main(){
        int n=gi(),k=gi();S=n+n+1,T=n+n+2;
        for(int i=1;i<=n;++i)a[i]=gi();
        for(int i=1;i<=n;++i)c[i]=gi();
        for(int i=1;i<=n;++i)link(S,i,1,c[a[i]]),link(i,i+n,1,-1e9),link(i+n,T,1,0);
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
                link(i+n,j,1,a[i]==a[j]?0:c[a[j]]);
        ll ans=1e9*n;
        if(k>n)k=n;while(k--)Mincost(ans);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    C# 窗体(登录界面)
    PHP中include与require的特点和区别说明
    PHP面对对象7大原则
    PHP设计模式 单例模式与工厂模式
    PHP面向对象总结 及 静态 抽象 接口
    PHP面向对象解析
    php常用函数整理
    PHP基础(二) 1、随机数和时间 2、字符串函数
    PHP基础(一) 数组
    php 数据库的增删改查
  • 原文地址:https://www.cnblogs.com/xzz_233/p/10109637.html
Copyright © 2011-2022 走看看