P3387 模板 縮點

2021-10-24 13:54:35 字數 2108 閱讀 4660

r es

ul

tresult

result

h yp

erli

nk

hyperlink

hyperl

ink de

scri

ptio

ndescription

descri

ptio

n 給定一張n

nn個點,m

mm條邊的有向圖,點有點權

找出一條路徑使得經過的點的權值和最大,點和邊可以重複經過,但是只算一次貢獻

資料範圍:n≤1

04,m

≤105

n\leq 10^4,m\leq 10^5

n≤104,

m≤105so

luti

on

solution

soluti

on容易發現每個環如果選的話,這個環都會直接選掉,所以我們可以把每個環縮成乙個點,它的點權就重新定義成所有點的取值和

接下來就是乙個簡單的dag

dp

dagdp

dagd

p了,設f

if_i

fi​表示以i

ii為終點的最大路徑和,顯然有fj=

max+

vj

f_j=max\+v_j

fj​=ma

x+vj

​,按照拓撲序轉移即可

時間複雜度:o(n

+m

)o(n+m)

o(n+m)co

de

code

code

#include

#include

#include

#include

#include

#define n 10010

#define m 200010

#define ll long long

using

namespace std;

int n,m,v[n]

,le[n]

,lg[n]

,tote,totg,a,b,rd[n]

,f[n]

;struct nodee[m]

,g[m]

;inline

void

adde

(int u,

int v)

;le[u]

=tote;

return;}

inline

void

addg

(int u,

int v)

;lg[u]

=totg;

return;}

bool vis[n]

;inline ll read()

int low[n]

,dfn[n]

,stk[n]

,top,cnt,which[n]

;inline

void

tarjan

(int x)

else

if(vis[y]

) low[x]

=min

(low[x]

,dfn[y]);

}if(dfn[x]

==low[x]

)return;}

}signed

main()

queue<

int>q;

for(

register

int i=

1;i<=n;i++)if

(which[i]

==i&&rd[i]==0

) q.

push

(i),f[i]

=v[i]

;while

(q.size()

)}int res=0;

for(

register

int i=

1;i<=n;i++

) res=

max(res,f[i]);

printf

("%d"

,res)

;}

P3387 模板 縮點

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

P3387 模板 縮點

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

P3387 模板 縮點

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