雖說是模板題,但是竟然中間有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 計算到達這個強連通分量時的最大權值 感覺這裡...