tarjan缩点+拓扑 不过样例 玄关求调
查看原帖
tarjan缩点+拓扑 不过样例 玄关求调
1020005
c20220525楼主2024/3/1 20:48
#include <bits/stdc++.h>
#define rg register
#define int long long
#define il inline
#define N 200005
using namespace std;
struct aa{
	int b,v;
}d[N];
int co[N],a[N],maxa,sum[N],n,m,dfn[N],f[N],low[N],st[N],top,cnt,tim,vis[N],be[N],tot;
vector<int> vv[N];
vector<int> v[N];
queue<int> q;
il void toposort(){
	for(rg int i = 1; i <= cnt; i++ ){
		f[i]=co[i];
	}
	while(!q.empty()){
		int a=q.front();
		q.pop();
		for(rg int i = 0; i < v[a].size(); i++ ){
			int y=v[a][i];
			f[y]=max(f[y],f[a]+co[y]);
			sum[y]--;
			if(sum[y]==0){
				q.push(y);
			}
		}
	}
	for(rg int i = 1; i <= cnt; i++ ){
		maxa=max(f[i],maxa);
	}
	printf("%lld",maxa);
}
il void tarjan(int u){
	st[++top]=u,vis[u]=1;
	dfn[u]=low[u]=++tim;
	for(rg int i = 0; i < vv[u].size(); i++ ){
		int w=vv[u][i];
		if(!dfn[w]){
			tarjan(w);
			low[u]=min(low[u],low[w]);
		}
		else if(vis[w]){
			low[u]=min(low[u],dfn[w]);
		}
	}
	if(dfn[u]==low[u]){
		cnt++;
		while(st[top]!=u){
			be[st[top]]=cnt;
			vis[st[top]]=0;
			co[cnt]++;
			top--;
		}
		vis[st[top]]=0;
		be[st[top]]=cnt;
		co[cnt]++;
		top--;
	}
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(rg int i = 1; i <= n; i++ ){
		scanf("%lld",&a[i]);
	}
	for(rg int i = 0; i < m; i++ ){
		int x,y;
		scanf("%lld%lld",&x,&y);
		if(a[x]<=a[y]){
			vv[x].push_back(y);
			d[tot].b=x,d[tot].v=y,tot++;
		}
		if(a[x]>=a[y]){
			vv[y].push_back(x);
			d[tot].b=y,d[tot].v=x,tot++;
		}
	}
	for(rg int i = 1; i <= n; i++ ){
		if(!dfn[i]){
			tarjan(i);
		}
	}
	for(rg int i = 0; i < tot; i++ ){
		int u=be[d[i].b], w=be[d[i].v];
		if(u!=w){
			v[u].push_back(w);
			sum[w]++;
		}
	}
	for(rg int i = 1; i <= cnt; i++ ){
		if(sum[i]==0) q.push(i);
	}
	toposort();
	return 0;
}
2024/3/1 20:48
加载中...