P3387 模板 縮點

2022-05-21 04:45:32 字數 1391 閱讀 4005

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

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

第一行兩個正整數 \(n,m\)

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

第三至 \(m+2\)行,每行兩個整數 \(u,v\),表示一條 \(u \rightarrow v\) 的有向邊。

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

輸入 #1

2 2

1 11 2

2 1

輸出 #1

2
【資料範圍】

對於 $100% $ 的資料,\(1 \leq n \leq 10^4,1 \leq m \leq 10^5\),點權$ \in [0,1000]$

演算法:tarjan 縮點 + dagdp

額外測試點1

#include#define mem(x) memset(x,0,sizeof(x))

using namespace std;

const int n=2e5;

int x[n],y[n];

int p[n];

int head[n],next[n],vet[n],edge;

int dfn[n],low[n];

bool vis[n];

int f[n];

int tim,tot,sum[n],color[n];

inline void add(int u,int v)

int st[n],top;

void tarjan(int u)

else if(vis[v])

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

} if(dfn[u]==low[u])

}}void dfs(int u)

f[u]+=mx;

}int main()

for(int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);

mem(head);

mem(next);

mem(vet);

edge=0;

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

if(color[x[i]]!=color[y[i]])

add(color[x[i]],color[y[i]]);

int ans=0;

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

}printf("%d\n",ans);

return 0;

}

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 模板 縮點

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

P3387 模板 縮點

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