[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('\n');}

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;
}
posted @ 2019-03-06 21:29  Hyscere  阅读(170)  评论(0编辑  收藏  举报