tarjan+记搜,40pts求条
查看原帖
tarjan+记搜,40pts求条
752094
MornHus楼主2023/10/15 21:28

有注释比较易懂

#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
#define maxm 100005
#define ll long long

int read(){
	int x=0;
	int f=1;
	char c=getchar();
	while(c>'9'||c<'0'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<1)+(x<<3)+(c^'0');
		c=getchar();
	}
	return x*f;
}

vector<int>g[maxn];//original gragh
vector<int>g1[maxn];//super gragh

int color[maxn];//color the super point
int vis[maxn];//in or not in stack 
int stack_[maxn];//stack 
int dfn[maxn];//time mark 
int low[maxn];//fathers' time that you can get the earliest 

int	val_[maxn];//super point val
int val[maxn];//point val

int deep, sum, index_;
//time,super point number,,stack top 
int n,m;

int dp[maxn];
//final dp ans;

void tarjan( int now ){
	dfn[now] = ++ deep ;
	low[now] = deep ;
	vis[now] = 1 ;
	stack_[++index_]=now;
	
//	cerr<<now<<' '<<deep<<' '<<dfn[now]<<endl;
	
	for(int i=0;i<g[now].size();i++){
		int to = g[now][i];
		if(!dfn[to]){
			tarjan(to);
			low[now] = min(low[now],low[to]);
		}else{
			if(vis[to]){
				low[now] = min(low[now],low[to]);
			}
		}
	}
	
	if(dfn[now]==low[now]){
		sum++;
		while(1){
			color[stack_[index_]]=sum;
			vis[stack_[index_]]=0;
			val_[sum]+=val[stack_[index_]];
			index_--;
			if(now==stack_[index_+1])break;
		}
	}
}

void dps(int now){
	if(dp[now])return;
	dp[now]=val_[now];
	int max_dp=0;
	for(int i=0;i<g1[now].size();i++){
		if(!dp[g1[now][i]])dps(g1[now][i]);
		max_dp=max(max_dp,dp[g1[now][i]]);
	}
	dp[now]+=max_dp;
}

void debug(){
	for(int i=1;i<=n;i++)cerr<<i<<' '<<dfn[i]<<' ';
	cerr<<endl;
}
int main(){
	n=read();
	m=read();
	
	for(int i=1;i<=n;i++){
		val[i]=read();
	}//in val
	
	for(int i=1,u,v;i<=m;i++){
		u=read();
		v=read();
		g[u].push_back(v);
	}//build original gragh
	
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
	//		cerr<<"tar";
			tarjan(i);
			
		}
	}// do tarjan on each point
	
//	debug();
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<g[i].size();j++){
			int to=g[i][j];
			if(color[i]!=color[to]){
				g1[i].push_back(to);
			}
		}
	}//build new super gragh
	
	int final_ans=0;
	for(int i=1;i<=sum;i++){
		if(!dp[i]){
			dps(i);
			final_ans=max(final_ans,dp[i]);
		}
	}//make dp on each super point
	
	cout<<final_ans;
	return 0;
}
2023/10/15 21:28
加载中...