求调tarjan 50pts
查看原帖
求调tarjan 50pts
127925
Kio_楼主2021/10/12 16:25

谢谢大佬;w;

#include<cstdio>
#include<bitset>
#include<queue>

using namespace std;

const int N = 1e4+10, M = 1e5+10;

int n,m;
int v[N], val[N];
int f[N];
int sta[N], tp, in[N<<1], dfn[N], low[N], cntt;
int scc[N], cnts;
bitset<N> stavis;

inline int max(int a, int b){return a>b?a:b;}
inline int min(int a, int b){return a<b?a:b;}
struct edge{
	int u,v,nxt;
	edge(int u=0,int v=0,int nxt=0):u(u),v(v),nxt(nxt){}
}e[M<<1]; int head[N<<1], cnt;
inline void addline(int u,int v){
	e[++cnt] = edge(u,v,head[u]), head[u] = cnt;
}

void tarjan(int x){
	dfn[x] = low[x] = ++cntt;
	sta[++tp] = x;
	stavis[x] = 1;
	for(int i=head[x];i;i=e[i].nxt){
		int y = e[i].v;
		if(!dfn[y]){
			tarjan(y);
			low[x] = min(low[x], low[y]);
		}
		else if(stavis[y]) low[x] = min(low[x], dfn[y]);
	}
	if(dfn[x] == low[x]){
		cnts++;
		do{
			int y = sta[tp];
			scc[y] = cnts;
			val[scc[y]] += v[y];
			stavis[y] = 0;
		}while(sta[tp--] != x);
	}
}

inline bool isd(int c){return '0'<=c&&c<='9';}
int read(){
	int num,c,f=1;
	for(;!isd(c=getchar());f=c);
	for(num=c^48;isd(c=getchar());(num*=10)+=c^48);
	return f^45?num:-num;
}

int main(){
	n=read(), m=read();
	cnts = n;
	for(int i=1;i<=n;i++) v[i] = read();
	for(int i=1;i<=m;i++){
		int u=read(), v=read();
		addline(u,v);
	}
	
	stavis.reset();
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
	
	for(int i=1;i<=n;i++){
		for(int j=head[i];j;j=e[j].nxt){
			int y = e[j].v;
			addline(scc[i], scc[y]);
			in[scc[y]] ++;
		}
	}
	
	queue<int> q;
	for(int i=n+1;i<=cnts;i++){
		if(!in[i]) q.push(i);
		f[i] = val[i];
	}
	while(!q.empty()){
		int x = q.front();
		q.pop();
		for(int i=head[x];i;i=e[i].nxt){
			int y = e[i].v;
			f[y] = max(f[y], f[x] + val[y]);
			in[y]--;
			if(!in[y]) q.push(y); 
		}
	}
	
	int ans=0;
	for(int i=n+1;i<=cnts;i++) ans = max(ans,f[i]);
	printf("%d",ans);
	return 0;
}
2021/10/12 16:25
加载中...