zoukankan      html  css  js  c++  java
  • [BZOJ3876] [AHOI2014&JSOI2014]支线剧情

    Description

    【故事背景】

    宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等。不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情。这些游戏往往都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情。

    【问题描述】

    JYY现在所玩的RPG游戏中,一共有N个剧情点,由1到N编号,第i个剧情点可以根据JYY的不同的选择,而经过不同的支线剧情,前往Ki种不同的新的剧情点。当然如果为0,则说明i号剧情点是游戏的一个结局了。

    JYY观看一个支线剧情需要一定的时间。JYY一开始处在1号剧情点,也就是游戏的开始。显然任何一个剧情点都是从1号剧情点可达的。此外,随着游戏的进行,剧情是不可逆的。所以游戏保证从任意剧情点出发,都不能再回到这个剧情点。由于JYY过度使用修改器,导致游戏的“存档”和“读档”功能损坏了,所以JYY要想回到之前的剧情点,唯一的方法就是退出当前游戏,并开始新的游戏,也就是回到1号剧情点。JYY可以在任何时刻退出游戏并重新开始。不断开始新的游戏重复观看已经看过的剧情是很痛苦,JYY希望花费最少的时间,看完所有不同的支线剧情。

    Input

    输入一行包含一个正整数N。

    接下来N行,第i行为i号剧情点的信息;

    第一个整数为,接下来个整数对,Bij和Tij,表示从剧情点i可以前往剧

    情点,并且观看这段支线剧情需要花费的时间。

    Output

    输出一行包含一个整数,表示JYY看完所有支线剧情所需要的最少时间。

    Sample Input

    6
    2 2 1 3 2
    2 4 3 5 4
    2 5 5 6 6
    0
    0
    0
    

    Sample Output

    24
    

    Solution

    有上下界最小费用可行流模板题...

    把不带费用的可行流魔改一下就好了。

    #include<bits/stdc++.h>
    using namespace std;
     
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
     
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    const int maxn = 2e5+10;
    const int inf = 1e9;
    
    int n,tot=1,s,t,S,T,cost;
    int ban[maxn],head[maxn],dis[maxn],vis[maxn],deg[maxn];
    struct edge{int to,nxt,w,c;}e[maxn<<1];
    
    void add(int u,int v,int w,int c) {e[++tot]=(edge){v,head[u],w,c},head[u]=tot;}
    void ins(int u,int v,int w,int c) {add(u,v,w,c),add(v,u,0,-c);}
    
    int bfs() {
    	memset(dis,63,(T+1)*4);
    	memset(vis,0,(T+1)*4);
    	queue<int > q;q.push(S);vis[S]=1,dis[S]=0;
    	while(!q.empty()) {
    		int x=q.front();q.pop();vis[x]=0;
    		for(int v,i=head[x];i;i=e[i].nxt)
    			if(e[i].w>0&&dis[v=e[i].to]>dis[x]+e[i].c) {
    				dis[v]=dis[x]+e[i].c;
    				if(!vis[v]) vis[v]=1,q.push(v);
    			}
    	}
    	return dis[T]<inf;
    }
    
    int dfs(int x,int f) {
    	vis[x]=1;
    	if(x==T) return cost+=dis[T]*f,f;
    	int used=0;
    	for(int v,i=head[x];i;i=e[i].nxt)
    		if((!vis[v=e[i].to]||v==T)&&e[i].w>0&&dis[v]==dis[x]+e[i].c) {
    			int d=dfs(v,min(f-used,e[i].w));
    			if(d>0) e[i].w-=d,e[i^1].w+=d,used+=d;
    			if(used==f) break;
    		}
    	return used;
    }
    
    int cost_flow() {
    	while(bfs()) dfs(S,inf);
    	return cost;
    }
    
    int main() {
    	read(n);
    	s=1,t=n+2,S=n+3,T=n+4;int ans=0;
    	for(int i=1;i<=n;i++) {
    		int m;read(m);
    		for(int j=1,x,y;j<=m;j++) {
    			read(x),read(y);ins(i,x,inf,y);ans+=y;
    			deg[i]--,deg[x]++;
    		}
    	}
    	for(int i=1;i<=n;i++) if(deg[i]>0) ins(S,i,deg[i],0);else ins(i,T,-deg[i],0);
    	for(int i=2;i<=n;i++) ins(i,t,inf,0);
    	ins(t,s,inf,0);
    	write(cost_flow()+ans);
    	return 0;
    }
    
  • 相关阅读:
    spark 查看 job history 日志
    Kafka集群安装
    spark总体概况
    hadoop distcp使用
    基于spark1.3.1的spark-sql实战-02
    HiveServer2 入门使用
    基于spark1.3.1的spark-sql实战-01
    Hive基础学习文档和入门教程
    HDFS HA与QJM(Quorum Journal Manager)介绍及官网内容整理
    Akka DEMO
  • 原文地址:https://www.cnblogs.com/hbyer/p/10486225.html
Copyright © 2011-2022 走看看