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 ...