P3387 模板 縮點

2022-04-06 18:41:07 字數 1552 閱讀 2401

縮點+dp

給定乙個n個點m條邊有向圖,每個點有乙個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。

允許多次經過一條邊或者乙個點,但是,重複經過的點,權值只計算一次。

輸入格式:

第一行,n,m

第二行,n個整數,依次代表點權

第三至m+2行,每行兩個整數u,v,表示u->v有一條有向邊

輸出格式:

共一行,最大的點權之和。

輸入樣例#1: 複製

2 2

1 11 2

2 1

輸出樣例#1: 複製

2

n<=10^4,m<=10^5,|點權|<=1000 演算法:tarjan縮點+dagdp

縮點成有點無環圖(樹),然後拓撲+dp

1 #include2 #include3 #include4 #include5 #include6

7using

namespace

std;89

const

int n = 20100;10

const

int m = 200100;11

struct

edgee[m],s[m]; //

不要混用!!!

14int

head[n],dfn[n],low[n],st[n],bel[n],h[n];

15int ru[n],q[1000000

],l,r,w[n],sw[n],ans[n];

16bool

vis[n];

17int

cnt,tn,tot,top,tot1;

1819 inline char

nc()

23 inline int

read()

3132 inline void add_edge(int u,int

v) 35 inline void add(int u,int

v) 38

void tarjan(int

u) 48

else

if(vis[v])

49 low[u] =min(low[u],dfn[v]);50}

51if (low[u]==dfn[u]) while (st[top+1] !=u);59}

60}6162

intmain()

70for (int i=1; i<=n; ++i)

71if (!dfn[i]) tarjan(i);

72for (int u=1; u<=n; ++u) 78}

79 l = 1,r = 0;80

for (int i=1; i<=cnt; ++i)

8384

while (l <=r) 93}

94int mx = 0;95

for (int i=1; i<=cnt; ++i)

98 printf("%d"

,mx);

99return0;

100 }

P3387 模板 縮點

r es ul tresult result h yp erli nk hyperlink hyperl ink de scri ptio ndescription descri ptio n 給定一張n nn個點,m mm條邊的有向圖,點有點權 找出一條路徑使得經過的點的權值和最大,點和邊可以重複...

P3387 模板 縮點

題解 qwq論這個題我開了多少陣列qwq 因為每個點走過多次權值只會計算1次 簡化問題 把題目給出的有向圖縮點,成為有向無環圖,然後拓撲排序跑最長路 首先tarjan縮點 然後強連通分量連邊 下面跑拓撲排序,入度為0的強連通分量 first 然後 dis 計算到達這個強連通分量時的最大權值 感覺這裡...

P3387 模板 縮點

給定乙個 n 個點 m 條邊有向圖,每個點有乙個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。允許多次經過一條邊或者乙個點,但是,重複經過的點,權值只計算一次。第一行兩個正整數 n,m 第二行 n 個整數,依次代表點權 第三至 m 2 行,每行兩個整數 u,v 表示一條 u ...