• BZOJ3876 AHOI/JSOI2014支线剧情(上下界网络流)


      原图所有边下界设为1上界设为inf花费为时间,那么显然就是一个上下界最小费用流了。做法与可行流类似。

      因为每次选的都是最短路增广,且显然不会有负权增广路,所以所求出来的可行流的费用就是最小的。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 310
    #define M 20010
    #define inf 100000000
    #define S 0
    #define T 301
    int n,p[N],t=-1,pre[N],q[N],d[N],degree[N],ans=0;
    bool flag[N];
    struct data{int to,nxt,cap,flow,cost;
    }edge[M]; 
    void addedge(int x,int y,int z,int cost)
    {
        t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=0,edge[t].cost=cost,p[x]=t;
        t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=0,edge[t].flow=0,edge[t].cost=-cost,p[y]=t;
    }
    int inc(int &x){x++;if (x>n+1) x-=n+1;return x;}
    bool spfa()
    {
        memset(d,42,sizeof(d));d[S]=0;
        memset(flag,0,sizeof(flag));
        int head=0,tail=1;q[1]=S;
        do
        {
            int x=q[inc(head)];flag[x]=0;
            for (int i=p[x];~i;i=edge[i].nxt)
            if (d[x]+edge[i].cost<d[edge[i].to]&&edge[i].flow<edge[i].cap)
            {
                d[edge[i].to]=d[x]+edge[i].cost;
                pre[edge[i].to]=i;
                if (!flag[edge[i].to]) 
                {
                    q[inc(tail)]=edge[i].to;
                    flag[edge[i].to]=1;
                }
            }
        }while (head!=tail);
        return d[T]<inf;
    }
    void ekspfa()
    {
        while (spfa())
        {
            int v=inf;
            for (int i=T;i!=S;i=edge[pre[i]^1].to)
            v=min(v,edge[pre[i]].cap-edge[pre[i]].flow);
            for (int i=T;i!=S;i=edge[pre[i]^1].to)
            ans+=v*edge[pre[i]].cost,edge[pre[i]].flow+=v,edge[pre[i]^1].flow-=v;
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3876.in","r",stdin);
        freopen("bzoj3876.out","w",stdout);
        const char LL[]="%I64d";
    #else
        const char LL[]="%lld";
    #endif
        n=read();
        memset(p,255,sizeof(p));
        for (int i=1;i<=n;i++)
        {
            int k=read();
            if (i>1) addedge(i,1,inf,0);
            while (k--)
            {
                int x=read(),y=read();
                addedge(i,x,inf,y);
                degree[i]++;degree[x]--;
                ans+=y;
            }
        }
        for (int i=1;i<=n;i++)
        if (degree[i]>0) addedge(i,T,degree[i],0);
        else if (degree[i]<0) addedge(S,i,-degree[i],0);
        ekspfa();
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    环形链表II 找环入口
    最短无序连续子数组 复制数组排序后与原数组相比
    和为K的子数组 暴力 或 hash+前缀
    在排序数组中查找元素的第一个和最后一个位置 二分法+递归
    NodeJs 批量重命名文件,并保存到指定目录
    NodeJs 批量图片瘦身,重设尺寸和图片质量并保存到指定目录
    NodeJs 获取照片拍摄日期和视频拍摄日期,并按日期目录存档
    Oracle迁移记录
    Oracle数据库迁移前的准备工作(创建用户并且分配权限及表空间)
    Oracle 11g R2性能优化 10046 event【转载】
  • 原文地址:https://www.cnblogs.com/Gloid/p/9425231.html
Copyright © 2020-2023  润新知