刚学OI一秒,弱鸡代码求调,感谢各位大佬qwq
查看原帖
刚学OI一秒,弱鸡代码求调,感谢各位大佬qwq
473401
zcxnb楼主2023/8/14 07:50
#include<bits/stdc++.h>
#define read(a) scanf("%d",&a)
using namespace std;
const int N=1e5+5;
int n,m,l,r,tim,top,cnt,rq,num;
int v[N],dfn[N],low[N],stak[N],col[N],rd[N],que[N],f[N],sum[N];
vector<int>a[N];
vector<int>b[N];
void tarjan(int x){
	dfn[x]=low[x]=++tim;
	stak[++top]=x;
	for(auto i:a[x]){
		if(!dfn[i]){//没被访问过 
			tarjan(i);
			low[x]=min(low[x],low[i]);
		}
		else if(!col[i]){//还在栈中,属于是一个强连通分量里的 
			low[x]=min(low[x],low[i]);
		}
	}
	if(dfn[x]==low[x]){//如果自己是强连通分量的头 
		col[x]=++cnt;
		sum[cnt]=v[x];
//		printf("lll=%d\n",x);
		while(stak[top]!=x){
			sum[cnt]+=v[stak[top--]];
			col[stak[top]]=cnt;
//			printf("col=%d\n",stak[top]);
		}  
		top--;
	} 
}
int main(){
	read(n);read(m);
	for(int i=1;i<=n;i++){
		 read(v[i]);
	}
	for(int i=1;i<=m;i++){
		read(l);read(r);
		a[l].push_back(r);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])  tarjan(i); 
	} 
//	for(int i=1;i<=n;i++){//便于理解 
//		printf("i=%d %d %d %d %d %d\n",i,dfn[i],low[i],col[i],sum[i],cnt);
//	}
	for(int i=1;i<=n;i++){//建图 
		for(auto j:a[i]){
			if(col[i]!=col[j]){
			  	b[col[i]].push_back(col[j]);//缩点后col相当于新的点编号
				rd[col[i]]++;
			}
		}
	}
//	for(int i=1;i<=cnt;i++){
//		for(auto j:b[i]){
//			printf("%d %d %d\n",i,j,sum[j]);
//		}
//	}
	for(int i=1;i<=cnt;i++){//建边之后cnt为新的点数 
		if(!rd[i]){
			que[++rq]=i;
//			printf("%d\n",f[i]);
		}
		f[i]=sum[i];
//		num=max(f[i],num);
	}
	for(int i=1;i<=rq;i++){
		for(auto j:b[que[i]]){
			f[j]=max(f[j],f[que[i]]+sum[j]);
			if(!--rd[j]){
				que[++rq]=j;
			}
			num=max(f[j],num);
		}
	}
	printf("%d",num);
}
/*
6 11
1
2
3
4
5
6
1 3
1 5
1 6
2 5
2 6
3 4
3 5
5 6
6 4
5 3
3 1*/ 

 
2023/8/14 07:50
加载中...