網路流24題 最長遞增子串行(拆點 最大流)

2021-08-28 05:15:04 字數 2257 閱讀 5502

給定正整數序列x1∼

xn

x_1 \sim x_n

x1​∼xn

​​​,以下遞增子串行均為非嚴格遞增。

計算其最長遞增子串行的長度 sss。

計算從給定的序列中最多可取出多少個長度為 s

ss 的遞增子串行。

如果允許在取出的序列中多次使用x

1x_1

x1​​​ 和 x

nx_n

xn​​,則從給定序列中最多可取出多少個長度為 s

ss 的遞增子串行。

如果每個點只能用一次,考慮拆點,變成前點和後點,前點向後點連一條容量為一條的邊即可。

第一問直接dp。

第二問考慮,按照上面的方法拆點,如果dp[

i]==

1dp[i] == 1

dp[i]=

=1,則s

ss向i

ii連容量為1的邊,若dp[

i]==

mxle

ndp[i] == mxlen

dp[i]=

=mxl

en,那麼i+n

i +n

i+n向t

tt連容量為1的邊。並且每個i

ii連i

ii到i+n

i+ni+

n容量為1的邊。跑最大流。

第三問把有條件的邊容量改為inf即可。

#include

using

namespace std;

typedef

double db;

typedef

long

long ll;

typedef

unsigned

long

long ull;

const

int nmax =

1e6+7;

const

int inf =

0x3f3f3f3f

;const ll linf =

0x3f3f3f3f3f3f3f3f

;const ull p =67;

const ull mod =

1610612741

;int n;

int a[nmax]

, dp[nmax]

;int

getdp()

} dp[i]

= tmp +1;

}int ans =0;

for(

int i =

1; i <= n;

++i)

return ans;

}struct dinic e[nmax<<1]

;void

init

(int n)

intadd_edge

(int u,

int v,

int c)

bool

bfs()}

}return vis[t];}

intdfs

(int x,

int a)

}return flow;

}int

maxflow

(int s,

int t)

return flow;

}} dinic;

intmain()

int s =

0, t =

2* n +1;

int mxlen =

getdp()

;printf

("%d\n"

, mxlen)

;

dinic.

init

(t);

for(

int i =

1; i <= n;

++i)

}int mxflow = dinic.

maxflow

(s, t)

;printf

("%d\n"

, mxflow)

; dinic.

init

(t);

for(

int i =

1; i <= n;

++i)

} mxflow = dinic.

maxflow

(s, t)

;printf

("%d\n"

, mxflow)

;return0;

}

網路流 24 題 最長遞增子串行

1 dp求一遍 2 所有點拆成入點和出點,對於沒個f i 1的1點連源點,每個f i ans1的點連匯點,每個點的入點和出點再連一條邊,所有容量為1,求一遍最大流。2 1和n可以用多次,所以對於點1和點n,入點和出的連邊的容量變為inf,如果需要連源點或匯點那麼容量也變為n,其餘容量為1,求一遍最大...

網路流24題 最長遞增子串行

輸入檔案 alis.in輸出檔案 alis.out簡單對比 時間限制 1 s 記憶體限制 128 mb 問題描述 給定正整數序列x1,xn。1 計算其最長遞增子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的遞增子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可...

網路流24題 最長遞增子串行

給定正整數序列x1,xn。1 計算其最長遞增子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的遞增子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的遞增子串行。設計有效演算法完成 1 2 3 提出的計算任務 第1 行有1個正整數n n 500...