萌妹子刚学OI,40pts,求助大佬
查看原帖
萌妹子刚学OI,40pts,求助大佬
356081
Night_7d5楼主2021/8/31 14:05
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
struct edge {
	int to,next;
}e[N*10],E[N*10];
int head[N],cnt=0;
void add(int u,int v) {
	e[++cnt].next=head[u];
	e[cnt].to=v;
	head[u]=cnt;
}
int Head[N],Cnt=0;
void Add(int u,int v) {
	E[++Cnt].next=Head[u];
	E[Cnt].to=v;
	Head[u]=Cnt;
}
int a[N],dfn[N],low[N],s[N],tot,top,t,p[N],flag[N];
bool out[N];
void tarjan(int u) {
	dfn[u]=low[u]=++tot;
	s[++top]=u;
	for(int i=head[u];i;i=e[i].next) {
		int v=e[i].to;
		if(!dfn[v]) {
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!out[v]) low[u]=min(dfn[v],low[u]);
	}
	if(dfn[u]==low[u]) {
		++t;
		while(s[top]!=u) {
			p[t]+=a[s[top]];
			flag[s[top]]=t;
			out[s[top]]=1;
			top--;
		}
			p[t]+=a[s[top]];
			flag[s[top]]=t;
			out[s[top]]=1;
			top--;
	}
}
int rd[N],f[N];
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1,u,v;i<=m;i++) {
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1;i<=n;i++) { //tarjan缩点 
		if(!dfn[i]) tarjan(i);
	}
	for(int u=1;u<=n;u++) { //重新建图,统计入度 
		for(int i=head[u];i;i=e[i].next) {
			int v=e[i].to;
			if(flag[v]!=flag[u]) {
				Add(flag[u],flag[v]);
				rd[flag[v]]++;
			}
		}
	}
	queue<int> q;
	for(int i=1;i<=t;i++) {
		f[i]=p[i];
		if(rd[i]==0) {
			q.push(i);
		} 
	}
	while(!q.empty()) { //拓扑排序+dp 
		int u=q.front();
		q.pop();
		for(int i=head[u];i;i=e[i].next) {
			int v=e[i].to;
			f[v]=max(f[v],f[u]+p[v]);
			rd[v]--;
			if(rd[v]==0) q.push(v);
		}
	}
	int ans=0;
	for(int i=1;i<=t;i++) {
		ans=max(ans,f[i]);
	}
	printf("%d",ans);
	return 0;
}
2021/8/31 14:05
加载中...