您的位置:首页 > 其它

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

2017-05-19 21:54 483 查看

3876: [Ahoi2014]支线剧情

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

HINT

JYY需要重新开始3次游戏,加上一开始的一次游戏,4次游戏的进程是

1->2->4,1->2->5,1->3->5和1->3->6。

对于100%的数据满足N<=300,0<=Ki<=50,1<=Tij<=300,Sigma(Ki)<=5000

#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 0x7fffffff
using namespace std;
const int N = 305;
int n,ans,cnt=1,T;
int last
,q
,d
;
bool inq
;
template <class T>
inline bool readIn(T &x)  {
T flag = 1;  char ch;
while(!(isdigit(ch = (char) getchar())) && ch != EOF)  if( ch == '-' )  flag = -1;
if(ch == EOF)  return false;
for(x = ch - 48; isdigit(ch = (char) getchar()); x = (x << 1) + (x << 3) + ch - 48);
x *= flag;
return true;
}
struct Edge{
int v,to,next,c;
}e[N*N];
void insert( int u, int v, int w, int c ){
e[++cnt].to = v; e[cnt].next = last[u]; last[u] = cnt; e[cnt].v = w; e[cnt].c = c;
e[++cnt].to = u; e[cnt].next = last[v]; last[v] = cnt; e[cnt].v = 0; e[cnt].c = -c;
}
bool spfa(){
int head = 0, tail = 1;
memset(inq,0,sizeof(inq));
for( int i = 0; i < T; i++ ) d[i] = inf;
q[0] = T; d[T] = 0; inq[T] = 1;
while( head != tail ){
int now = q[head++]; if( head == T ) head = 0;
for( int i = last[now]; i; i = e[i].next )
if( e[i^1].v && d[now]-e[i].c < d[e[i].to] ){
d[e[i].to] = d[now]-e[i].c;
if( !inq[e[i].to] ) { inq[e[i].to] = 1; q[tail++] = e[i].to; if( tail == T ) tail = 0; }
}
inq[now] = 0;
}
return d[0] != inf;
}
int dfs( int x, int f ){
inq[x] = 1;
if( x == T ) return f;
int w, used = 0;
for( int i = last[x]; i; i = e[i].next )
if( d[x]-e[i].c == d[e[i].to] && !inq[e[i].to] && e[i].v ){
w = dfs( e[i].to, min(f-used,e[i].v) );
e[i].v -= w; e[i^1].v += w; used += w; ans += w*e[i].c;
if( f == used ) return f;
}
return used;
}
void zkw(){
while(spfa()){
inq[T] = 1;
while( inq[T] ){
memset(inq,0,sizeof(inq));
dfs(0,inf);
}
}
}
int main(){
readIn(n); T = n+1;
for( int i = 1; i <= n; i++ ){
int k; readIn(k);
insert(i,T,k,0);
insert(i,1,inf,0);
for( int j = 1; j <= k; j++ ){
int uu,ww; readIn(uu); readIn(ww);
insert(i,uu,inf,ww);
insert(0,uu,1,ww);
}
}
zkw();
printf("%d", ans);
return 0;
}


附poj2396 TLE

#include<iostream>
#include<cstring>
#include<cstdio>
#define INF 0x7fffffff
using namespace std;
const int N = 1005;
bool flag;
int S,T,SS,TT,NN;
int n,m,cnt=1;
int last
,cur
,h
,q
,d
;
int l[305][405],r[305][405];
template <class T>
inline bool readIn(T &x)  {
T flag = 1;  char ch;
while(!(isdigit(ch = (char) getchar())) && ch != EOF)  if( ch == '-' )  flag = -1;
if(ch == EOF)  return false;
for(x = ch - 48; isdigit(ch = (char) getchar()); x = (x << 1) + (x << 3) + ch - 48);
x *= flag;
return true;
}
struct Edge{ int to,v,next; } e[N*N];
void insert(int u,int v,int w){
e[++cnt].to = v; e[cnt].next = last[u]; last[u] = cnt; e[cnt].v = w;
e[++cnt].to = u; e[cnt].next = last[v]; last[v] = cnt; e[cnt].v = 0;
}
bool bfs(){
memset(h,-1,sizeof(h));
int head = 0, tail = 1; q[0] = SS; h[SS] = 0;
while( head != tail ){
int now = q[head++];
for( int i = last[now]; i; i = e[i].next )
if( e[i].v && h[e[i].to] == -1 ){
h[e[i].to] = h[now] + 1;
q[tail++] = e[i].to;
}
}
return h[TT] != -1;
}
int dfs( int x, int f ){
if( x == TT ) return f;
int w, used = 0;
for( int i = cur[x]; i; i = e[i].next )
if( h[e[i].to] == h[x] + 1 ){
w = dfs(e[i].to, min(e[i].v,f-used));
e[i].v -= w; e[i^1].v += w; used += w;
if( e[i].v ) cur[x] = i; if( used == f ) return f;
}
if(!used) h[x] = 1;
return used;
}
void dinic() {while(bfs()){for(int i=0;i<=TT;i++)cur[i]=last[i];dfs(SS,INF);} }
bool right(){
for( int i = S; i <= T; i++ ){
if( d[i] > 0 ) insert(SS,i,d[i]);
if( d[i] < 0 ) insert(i,TT,-d[i]);
} dinic();
for( int i = last[SS]; i; i = e[i].next) if(e[i].v) return false;
return true;
}
int main(){
scanf("%d", &NN);
int x,y,z; char ch[10];
while( NN-- ){
scanf("%d%d", &n, &m);cnt=1;
memset(last,0,sizeof(last)); cnt = 1; memset(d,0,sizeof(d));
for( int i = 0; i <= 300; i++ ) for( int j = 0; j <= 300; j++ ) l[i][j] = 0, r[i][j] = 1000;
flag = 0; S = 0; T = n+m+1; SS = T+1; TT = T+2;
for( int i = 1,x; i <= n; i++ ) readIn(x), insert(S,i,0), d[S] -= x, d[i] += x;
for( int i = 1,x; i <= m; i++ ) readIn(x), insert(n+1,T,0), d[n+i] -= x, d[T] += x;
int Q; scanf("%d", &Q);
while(Q--){
readIn(x); readIn(y); scanf("%s",ch); readIn(z);
if( !x && !y ) for( int i = 1; i = n; i++ ) for( int j = 1; j <= m; j++ ){
if( ch[0] == '=' ) l[i][j+n] = r[i][j+n] = z;
if( ch[0] == '>' ) l[i][j+n] = max(l[i][j+n],z+1);
if( ch[0] == '<' ) r[i][j+n] = min(r[i][j+n],z-1);
}if( !x && y ) for( int i = 1; i <= n; i++ ){
if( ch[0] == '=' ) l[i][y+n] = r[i][y+n] = z;
if( ch[0] == '>' ) l[i][y+n] = max(l[i][y+n],z+1);
if( ch[0] == '<' ) r[i][y+n] = min(r[i][y+n],z-1);
}if( x && !y ) for( int j = 1; j <= m; j++ ){
if( ch[0] == '=' ) l[x][j+n] = r[x][j] = z;
if( ch[0] == '>' ) l[x][j+n] = max(l[x][j+n],z+1);
if( ch[0] == '<' ) r[x][j+n] = min(r[x][j+n],z-1);
}if( x && y ){
if( ch[0] == '=' ) l[x][y+n] = r[x][y+n] = z;
if( ch[0] == '>' ) l[x][y+n] = max(l[x][y+n],z+1);
if( ch[0] == '<' ) r[x][y+n] = min(r[x][y+n],z-1);
}
} for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ){
if( l[i][j+n] > r[i][j+n] ) flag = 1;
insert(i,j+n,r[i][j+n]-l[i][j+n]);
d[i] -= l[i][j+n];
d[j+n] += l[i][j+n];
}
if( flag ){ printf("IMPOSSIBLE\n"); continue; }
insert(T,S,INF);
if(right()){
int t = n+m+1;
for( int i = 1; i <= n; i++ ){
for( int j = 1; j <= m; j++ ){
printf("%d",e[(t<<1)^1].v+l[i][j+n]);
if( j != m )printf(" "); t++;
} printf("\n");
}
} else printf("IMPOSSIBLE\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: