BZOJ 3876: [Ahoi2014 & Jsoi2014] story line active exchange bounds Cost Flow

Creative Commons License Copyright: Attribution, allow others to create paper-based, and must distribute paper (based on the original license agreement with the same license Creative Commons )

title

BZOJ 3876
LUOGU 4043
Description

[Background] story
otaku JYY love to play RPG games, such as Legend, Xuanyuanjian, and so on. But JYY not like the battle scenes, but the average similar drama full of pains and sorrows of the story. These games tend to have a lot of the story line, now JYY want to spend the least time to read all the story extension.
[Problem Description]
JYY now playing RPG games, a total of N plot points, numbered from 1 to N, the i-th plot points according to different selection JYY, but through a different story line, went to Ki different the new plot point. Of course, if it is 0, then the number i is a plot point in the final game.
JYY watch a story extension will take some time. JYY beginning at No. 1 plot point, which is the start of the game. Obviously any plot point is a number from 1 up to the point of the story. In addition, as the game progresses, the plot is irreversible. Therefore, to ensure the game from any point of the story, we can no longer return to this plot point. Since JYY excessive use of modifier, resulting in the game's "Archive" and "Read file" function is damaged, so in order to return to the previous JYY plot point, the only way is to exit the current game and start a new game, is back No. 1 to the plot point. JYY can quit the game at any time and start again. Constantly re-watch start a new game has already seen the story is very painful, JYY want to spend the least time watching all the different story extension.

Input

Input line contains a positive integer N.
Next N lines, i-behavior information number i plot point;
the first integer, followed by a pair of integers, Bij and Tij, represents the story from the point i can go play
situation point, and watch this story extension takes time.

Output

Output line contains an integer that indicates the minimum time to read all JYY story line required.

Sample Input

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

Sample Output

24

HINT

3 JYY need to start the game, with the beginning of the one game, the game is progress 4
1-> 2-> 4,1> 2-> 5,1> 3-> 5 and 1-> 3 -> 6.
To 100% of the data satisfies N <= 300,0 <= Ki < = 50,1 <= Tij <= 300, Sigma (Ki) <= 5000

Source

Round2 By Anonymous Upload

analysis

It is actually nothing to say, look uncle b l O g blog PoPoQQQ

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=310,maxm=1e5+10,inf=0x3f3f3f3f;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1, ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}

template<typename T>inline void write(T x)
{
	if (!x) { putchar('0'); return ; }
	if (x<0) putchar('-'), x=-x;
	T num=0, ch[20];
	while (x) ch[++num]=x%10+48, x/=10;
	while (num) putchar(ch[num--]);
}

int ver[maxm],edge[maxm],Next[maxm],cost[maxm],head[maxn],len=1;
inline void add(int x,int y,int z,int c)
{
	ver[++len]=y,edge[len]=z,cost[len]=c,Next[len]=head[x],head[x]=len;
	ver[++len]=x,edge[len]=0,cost[len]=-c,Next[len]=head[y],head[y]=len;
}

int ans,M[maxn];//统计 流入量-流出量
inline void insert(int x,int y,int up,int low,int c)
{
	add(x,y,up-low,c);
	if (low) { M[y]+=low,M[x]-=low,ans+=c*low; }
}

int ss,tt,s,t;
int dist[maxn],incf[maxn],pre[maxn];
bool vis[maxn];
inline bool spfa()
{
	memset(dist,0x3f,sizeof(dist));
	memset(vis,0,sizeof(vis));
	queue<int>q;q.push(s);
	dist[s]=0,vis[s]=1,incf[s]=1<<30;
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		for (int i=head[x]; i; i=Next[i])
		{
			if (!edge[i]) continue;
			int y=ver[i];
			if (dist[y]>dist[x]+cost[i])
			{
				dist[y]=dist[x]+cost[i];
				incf[y]=min(incf[x],edge[i]);
				pre[y]=i;
				if (!vis[y]) q.push(y),vis[y]=1;
			}
		}
	}
	if (dist[t]==inf) return false;
	else return true;
}

long long maxflow;
inline void update()
{
	int x=t;
	while (x!=s)
	{
		int i=pre[x];
		edge[i]-=incf[t];
		edge[i^1]+=incf[t];
		x=ver[i^1];
	}
	maxflow+=incf[t];
	ans+=dist[t]*incf[t];
}

int main()
{
	int n;read(n);
	ss=0,tt=n+1,s=n+2,t=n+3;//ss,tt是题中所给源汇点,s,t为超级源汇点
	insert(ss,1,inf,0,0),insert(tt,ss,inf,0,0);
	for (int i=1,k; i<=n; ++i)
	{
		read(k);insert(i,tt,inf,0,0);
		for (int j=1,x,z; j<=k; ++j) read(x),read(z),insert(i,x,inf,1,z);//因为他的上界都是INF,下界都是1,所以就
	}
	for (int i=ss; i<=tt; ++i)
		if (M[i]>0) add(s,i,M[i],0);//流入量>流出量,源点连向此点
		else add(i,t,-M[i],0);//流入量<流出量,此点连向汇点
	while (spfa()) update();//找循环流啦
	write(ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/huashuimu2003/article/details/93517185