【bzoj3876】支线剧情

要求在dag里每条边上界INF下界1费用t。

裸上下界费用流,好像没有什么特定的写法。

首先每条边肯定至少走一次,不妨直接把每条边下界的费用先算上。原来的边正常连容量INF费用t,每个点向1连边表示可以随时返回。由于先计算了下界的费用而忽略下界,所以会导致流量不守恒,考虑普通上下界网络流的写法,新建原点s汇点t,统计每个点下界时流出的流量和流入的流量,此题即出度和入度,令d=入度-出度,若d>0则S向这个点连容量为d费用为0的边,若d<0则向T连容量为-d费用为0的边,跑一遍mcmf加上原来的费用就好了。

#include<bits/stdc++.h>
#define maxn 405
#define maxm 100005
#define INF 0x7f7f7f7f

using namespace std;

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}

struct scsc{
    int next,from,to,w,c;
}edge[maxm<<1];

int Len,head[maxn],ind[maxn],otd[maxn],Sum;

void addedge(int u,int v,int w,int c){
    edge[++Len].to=v;edge[Len].from=u;edge[Len].w=w;edge[Len].c=c;edge[Len].next=head[u];head[u]=Len;
    edge[++Len].to=u;edge[Len].from=v;edge[Len].w=0;edge[Len].c=-c;edge[Len].next=head[v];head[v]=Len;
}

int vis[maxn],d[maxn];

int spfa(int s,int t){
    queue<int>Q;
    for(int i=s;i<=t;++i)vis[i]=0;
    for(int i=s;i<=t;++i)d[i]=INF;
    Q.push(s);vis[s]=1;d[s]=0;
    while(!Q.empty()){
        int u=Q.front();Q.pop();
        for(int i=head[u];i;i=edge[i].next){
            int v=edge[i].to;
            if(edge[i].w&&d[v]>d[u]+edge[i].c){
                d[v]=d[u]+edge[i].c;
                if(!vis[v]){
                    vis[v]=1;
                    Q.push(v);
                }
            }
        }
        vis[u]=0;
    }
    return d[t]!=INF;
}

int ans=0;

int dfs(int u,int f,int t){
    vis[u]=1;
    if(u==t)return f;
    int used=0,w;
    for(int i=head[u];i&&used<f;i=edge[i].next){
        int v=edge[i].to;
        if(edge[i].w&&d[v]==d[u]+edge[i].c&&!vis[v]){
            w=dfs(v,min(f-used,edge[i].w),t);
            edge[i].w-=w;
            edge[i^1].w+=w;
            used+=w;
            ans+=edge[i].c*w;
        }
    }
    return used;
}

void mcmf(int s,int t){
    while(spfa(s,t)){
        vis[t]=1;
        while(vis[t]){
            for(int i=s;i<=t;++i)vis[i]=0;
            dfs(s,INF,t);
        }
    }
}

int n;

int main(){
    n=read();int f1,f2;
    int S=0,T=n+1;Len=1;
    for(int i=1;i<=n;++i){
        otd[i]=read();
        for(int j=1;j<=otd[i];++j){
            f1=read();f2=read();
            ++ind[f1];Sum+=f2;
            addedge(i,f1,INF,f2);
        }
    }
    for(int i=2;i<=n;++i)addedge(i,1,INF,0);
    for(int i=2;i<=n;++i){
        int du=ind[i]-otd[i];
        if(du>0)addedge(S,i,du,0);
        else addedge(i,T,-du,0);
    }
    mcmf(S,T);
    printf("%d\n",ans+Sum);
    return 0;
}
时间: 2024-08-25 09:06:02

【bzoj3876】支线剧情的相关文章

[AHOI2014][bzoj3876] 支线剧情 [上下界费用流]

题面 传送门 思路 转化模型:给一张有向无环图,每次你可以选择一条路径走,花费的时间为路径上边权的总和,问要使所有边都被走至少一遍(可以重复),至少需要花费多久 走至少一遍,等价于覆盖这条边 也就是说,我们要找这个图的一个可重复的路径覆盖 路径覆盖让我们想到什么算法了呢? 网络流啊! 我们考虑建立网络流图模型. 这道题里面有个关键:走过一条边,走几次就要花几次的费用,这想到什么? 费用流嘛! 我们定义走一次路径会给这条路径上的所有边增加1的流量,再给所有边赋一个费用等于边权 这样,我们只要设每条

BZOJ3876[AHOI2014]支线剧情

Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情. 这些游戏往往都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩的RPG游戏中,一共有N个剧情点,由1到N编号,第i个剧情点可以根据JYY的不同的选择,而经过不同的支线剧情,前往Ki种不同的新的剧情点.当然如果为0,则说明i号剧情点是游戏的一个结局了. JYY观看一个支线剧情需要一定的时间

bzoj3876【Ahoi2014】支线剧情

3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 485  Solved: 297 [Submit][Status][Discuss] Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩

刷题总结——支线剧情(bzoj3876费用流)

题目: [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩的RPG游戏中,一共有N个剧情点,由1到N编号,第i个剧情点可以根据JYY的不同的选择,而经过不同的支线剧情,前往Ki种不同的新的剧情点.当然如果为0,则说明i号剧情点是游戏的一个结局了. JYY观看一个支线剧情需要一定的时间.JYY一开始处

【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status][Discuss] Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩的R

bzoj3876 [Ahoi2014&amp;Jsoi2014]支线剧情

3876: [Ahoi2014&Jsoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2180  Solved: 1300[Submit][Status][Discuss] Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述

BZOJ 3876 支线剧情 | 有下界费用流

BZOJ 3876 支线剧情 | 有下界费用流 题意 这题题面搞得我看了半天没看懂--是这样的,原题中的"剧情"指的是边,"剧情点"指的才是点. 题面翻译过来大概是这样: 有一个DAG,每次从1号点出发,走过一条路径,再瞬移回1号点.问:想要遍历所有的边,至少要走多少路程(瞬移回1号点不算路程). 题解 我们用有上下界费用流的模型,建个图: 原图中的每条边,流量范围是\([1, +\infty]\),表示至少走一次,可以走无限次,这条边的费用就是边权. 原图中的每个

C++之路进阶——最小费用最大流(支线剧情)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 542  Solved: 332[Submit

bzoj 3876 [Ahoi2014]支线剧情(有上下界的最小费用流)

3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 484  Solved: 296[Submit][Status][Discuss] Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩的R

BZOJ 3876 【AHOI2014】 支线剧情

题目链接:支线剧情 这道题就是一道裸裸的上下界网络流--只不过这道题边带了权,那么建出图之后跑费用流即可. 首先需要新建超级源\(S\)和超级汇\(T\).对于这道题,对于一条边\((u,v,z)\),我们从\(S\)向\(v\)连一条容量为\(1\),费用为\(z\)的边,保证下界:从\(u\)向\(T\)连一条容量为\(1\),费用为\(0\)的边,也是用来保证下界的.由于没有上界,所以直接从\(u\)向\(v\)连一条容量为\(INF\),费用为\(z\)的边即可. 注意这道题可以在任意一