蒟蒻求助 70分 wa 4,5,7
查看原帖
蒟蒻求助 70分 wa 4,5,7
1206518
Nervegas楼主2024/7/11 17:35
#include<bits/stdc++.h>
using namespace std;
const int N = 10010,M = 2000010;

int dfn[N],low[N],timestamp,id[N],scc_cnt;
int stk[N],top;
int n,m;
int cnt;
int size[N];//记录每个强连通分量里的点权和; 
int a[N];
int f[N],ans,maxnn;
int e[M],h[N],hs[N],ne[M],idx;
bool in_stk[N];

void add(int h[],int a,int b){
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx++;
} 

void tarjan(int u){
	dfn[u] = low[u] = ++timestamp;
	stk[++top] = u;
	in_stk[u] = true; 
	for(int i = h[u] ; ~i ; i = ne[i]){
		int v = e[i];
		if(!dfn[v]){
			tarjan(v);
			low[u] = min(low[u],low[v]);
		}
		else if(in_stk[v]){
			low[u] = min(low[u],dfn[v]);
		}
	}
	if(dfn[u] == low[u]){
		++scc_cnt;
		int y; 
		do{
			y = stk[top--];
			in_stk[y] = false;
			id[y] = scc_cnt;
			size[scc_cnt] += a[y];
		}while(y != u);
	}
}

void search(int x){//记忆化搜索 
	if(f[x]){
		return;
	}
	f[x] = size[x];
	for(int i = hs[x] ; ~i ; i = ne[i]){
		int v = e[i];//遍历能到达的点;
		if(!f[v]){
			search(v);
		}
		maxnn = max(maxnn,f[v]); 
	}
	f[x] += maxnn;//不断记录更新f 
}

int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	memset(h,-1,sizeof(h));
	memset(hs,-1,sizeof(h));
	cin >> n >> m;
	for(int i = 1 ; i <= n ; i++){
		cin >> a[i];
	}
	for(int i = 1 ; i <= m ; i++){
		int u,v;
		cin >> u >> v;
		add(h,u,v);
	}
	for(int i = 1 ; i <= n ; i++){
		if(!dfn[i]){
			tarjan(i);
		}
	}
	for(int i = 1 ; i <= n ; i++){
		for(int j = h[i] ; ~j ; j = ne[j]){
			int v = e[j];
			int a = id[i];
			int b = id[v];
			if(a != b){
				add(hs,a,b);
			}
		}
	}
	for(int i = 1 ; i <= scc_cnt ; i++){
		if(!f[i]){//遍历新图的每一个点 
			search(i);
			ans = max(ans,f[i]);
		}
	}
	cout << ans << endl;
	return 0;
}
2024/7/11 17:35
加载中...