缩点
缩点
缩点就是在求完强连通分量后新建一个结构体,将每一个强连通分量看做一个新的点,建一个新的图。
P3387
#include <iostream>
#include <cstdio>
using namespace std;
long long read(){
long long x = 0; int f = 0; char c = getchar();
while(c < '0' || c > '9') f |= c == '-', c = getchar();
while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f? -x:x;
}
int n, m, w[10004];
struct szh{
int next, x, y;
}a[100005], b[100005];
int hd[10004], cnt, dfn[10004], low[10004], s[10004], top;
int in[10004], F[10004], ans, H[10004], d[10004];
bool vis[10004];
inline void add(int x, int y){
a[++cnt].x = x = read(),a[cnt].y = y = read(),a[cnt].next = hd[x], hd[x] = cnt;
}
void Tarjan(int u){
dfn[u] = low[u] = ++cnt, vis[u] = 1, s[++top] = u;
for(int i = hd[u], v; v = a[i].y, i; i = a[i].next)
if(!dfn[v]){
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v]) low[u] = min(low[u], dfn[v]);
if(low[u] == dfn[u])
while(int k = s[top--]){
F[k] = u, vis[k] = 0;
if(k == u) break;
w[u] += w[k];
}
}
int main(){
n = read(); m = read();
for (int i = 1; i <= n ;++i) w[i] = read();
for (int i = 1, x, y; i <= m; ++i) add(x,y);
cnt = 0;
for(int i = 1; i <= n; ++i) if(!dfn[i]) Tarjan(i);
cnt = 0;
for(int i = 1; i <= m; ++i){
int x = F[a[i].x], y = F[a[i].y];
if(x != y) b[++cnt].x = x, b[cnt].y = y, b[cnt].next = H[x], H[x] = cnt, in[y]++;
}
top = 0;
for(int i = 1; i<= n; ++i)
if(F[i] == i && !in[i]) s[++top] = i, d[i] = w[i];
while(top){
int u = s[top--];
for(int i = H[u], v; v = b[i].y, i; i = b[i].next){
d[v] = max(d[v], d[u] + w[v]);
if(--in[v] == 0) s[++top] = v;
}
}
for(int i = 1; i <= n; ++i) ans = max(ans,d[i]);
printf("%d\n", ans);
return 0;
}
欢迎指正评论O(∩_∩)O~~