#include<bits/stdc++.h>
//luoguP3387
using namespace std;
typedef long long ll;
int n, m, u, v, maxq;//缩点后节点最大编号
struct Pair{
int u, v;
bool operator==(const Pair &T)const{
return u == T.u && v == T.v;
}
bool operator<(const Pair &T)const{
if (u != T.u)
return u < T.u;
return v < T.v;
}
};
struct G{
int u, v, nxt;
}e[200005], ef[200005], en[200005];//原图,反图,缩点后的图
map<Pair, int> mp;
int head[100005], pos;//同上
int headf[100005], posf;
int headn[100005], posn;
int dq[100005];//原点权
int ndq[100005];//缩点后点权
int qf[100005];//点i属于哪个强连通分量
int dp[100005];
int r[100005];
vector<int> wd;//dfs序
void addEdge(G *e, int *head, int &pos, int u, int v)
{
e[++pos] = {u, v, head[u]};
head[u] = pos;
}
bool vis[100005];
void dfs_f(int u)
{
vis[u] = true;
wd.push_back(u);
for (int i = headf[u];i;i = ef[i].nxt)
if (!vis[ef[i].v])
dfs_f(ef[i].v);
}
void dfs(int u, int k)
{
vis[u] = true;
qf[u] = k;
ndq[k] += dq[u];
for (int i = head[u];i;i = e[i].nxt)
if (!vis[e[i].v])
dfs(e[i].v, k);
}
void makeAns()
{
//for (int i = 1;i <= maxq; ++i)
// printf("%d\n", ndq[i]);
mp.clear();
for (int i = 1;i <= pos; ++i)
{
int ku = e[i].u, kv = e[i].v;
if (qf[ku] != qf[kv] && !mp[{qf[ku], qf[kv]}])
addEdge(en, headn, posn, qf[ku], qf[kv]), mp[{qf[ku], qf[kv]}] = 1, ++r[qf[kv]]/*,
printf("addEdge %d, %d\n", qf[ku], qf[kv])*/;
}
int ansi = 0;
queue<int> q;
for (int i = 1;i <= maxq; ++i)
if (!r[i])
q.push(i), dp[i] = ndq[i]/*, printf("Cls dp[%d] = %d\n", i, ndq[i])*/;
while (q.size())
{
int c = q.front();
q.pop();
for (int i = headn[c];i;i = en[i].nxt)
{
int ku = en[i].u, kv = en[i].v;
dp[kv] = max(dp[kv], dp[ku] + ndq[kv]);
//printf("Update dp[%d]:to dp[%d](= %d) + %d\n", kv, ku, dp[ku], ndq[kv]);
//printf("");
--r[kv];
if (!r[kv])
q.push(kv);
}
}
for (int i = 1;i <= maxq; ++i)
ansi = max(ansi, dp[i])/*, printf("dp[%d] = %d\n", i, dp[i])*/;
printf("%d", ansi);
}
int main()
{
//freopen("a.in", "r", stdin);
//freopen("my.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int i = 1;i <= n; ++i)
scanf("%d", dq + i);
for (int i = 1;i <= m; ++i){
scanf("%d%d", &u, &v);
if (u != v && !mp[{u, v}])
addEdge(e, head, pos, u, v), addEdge(ef, headf, posf, v, u),
mp[{u, v}] = 1;
}
for (int i = 1;i <= n; ++i)
if (!vis[i])
dfs_f(i);
memset(vis, 0, sizeof(vis));
for (int i = wd.size() - 1;i >= 0; --i)
if (!vis[wd[i]])
dfs(wd[i], ++maxq);
makeAns();
return 0;
}
rt.
40pts->60pts->90pts
蒟蒻调不动了
玄关
求调