题目:给定一个有向图(可能含环)及其各点权值,求一条经过点权值和最大的路径(重复经过的点只计算一次)
个人思路是先用tarjan找强联通分量然后锁点变成无环图再dfs,不知道为啥MLE了
时间限制:1000ms,内存限制:256MB
点数不超过104,边数不超过105,各点权值不超过103
#include<bits/stdc++.h>
using namespace std;
int n = 0, m = 0;
vector<int> g[10001], g2[10001];
int a[10001] = {0}, a2[10001] = {0};
int low[10001] = {0}, dfn[10001] = {0};
stack<int> s;
vector<pair<int, int> > edge;
int newp[10001] = {0}, tail = 1;
int vis[10001] = {0};
void tarjan(int x) {
s.push(x);
for(int i = 0; i < g[x].size(); i++) {
int y = g[x][i];
if(dfn[y]) {
low[x] = min(low[x], dfn[y]);
} else {
dfn[y] = low[y] = dfn[x] + 1;
tarjan(y);
low[x] = min(low[x], low[y]);
}
}
if(dfn[x] == low[x]) {
while(s.top() != x) {
newp[s.top()] = tail;
a2[tail] += a[s.top()];
s.pop();
}
newp[x] = tail;
a2[tail] += a[x];
tail++;
s.pop();
}
}
int dfs(int x, int s) {
int dis = s;
for(int i = 0; i < g2[x].size(); i++) {
int y = g[x][i];
dis = max(dis, dfs(y, s + a2[y]));
}
return dis;
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
for(int i = 0; i < m; i++) {
int u = 0, v = 0;
cin >> u >> v;
g[u].push_back(v);
edge.push_back(make_pair(u, v));
}
for(int i = 1; i <= n; i++) {
if(!dfn[i]) {
tarjan(i);
}
}
for(int i = 0; i < m; i++) {
int u = edge[i].first, v = edge[i].second;
u = newp[u];
v = newp[v];
g2[u].push_back(v);
}
int ans = 0;
for(int i = 1; i < tail; i++) {
ans = max(ans, dfs(i, a2[i]));
}
cout << ans;
return 0;
}