P3387 模板 縮點 tarjan

2022-03-13 05:44:01 字數 1793 閱讀 2914

雖說是模板題,但是竟然中間有dp的部分...先tarjan縮點,重新建圖.然後記憶化搜尋,搜尋dag中的最小環.

題幹:

題目背景

縮點+dp

題目描述

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

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

輸入輸出格式

輸入格式:

第一行,n,m

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

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

輸出格式:

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

輸入輸出樣例

輸入樣例#

1: 複製22

1112

21輸出樣例#

1: 複製2說明

n<=10^4,m<=10^5,點權<=1000

演算法:tarjan縮點+dagdp

**:

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

#define duke(i,a,n) for(int i = a;i <= n;i++)

#define lv(i,a,n) for(int i = a;i >= n;i--)

#define clean(a) memset(a,0,sizeof(a))

const

int inf = 1

<< 30

;typedef

long

long

ll;typedef

double

db;template

void read(t &x)

template

void

write(t x)

int lst[100010],dfn[100010],low[100010],n,m,tot = 0,str[100010],top = 0,vis[100010

];int num[100010],chu[100010],col[100010],len = 0,ans = 0,ru[100001

];int hr[100010],kk[100010],f[100010

];struct

node

a[100010

];void add(int x,int

y)void tarjan(int

x)

else

if(vis[y])

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

while(x !=v);

}}void search(int

x) f[x] +=maxnum;

}int

main()

duke(i,

1,m)

duke(i,

1,n)

clean(lst);

int u =len;

len = 0

; duke(i,

1,u)

}int maxn = 0

; duke(i,

1,ans)

}printf(

"%d\n

",maxn);

return0;

}/*2 21 1

1 22 1

*/

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 計算到達這個強連通分量時的最大權值 感覺這裡...