#tarjan+Topology# [luogu P3387] 【模板】缩点

Title

P3387 【模板】缩点



Code

#include
#include
#include
#define rep(i,x,y) for(register int i=x;i<=y;i++)
using namespace std; 
const int N=1e4+15; 
struct node{int x,y,next;}a[10*N],b[10*N]; 
int n,m,low[N],dfn[N],list[N],s[N],belong[N],p[N],in[N]; 
int num,naa,tot,head[N],sum,dis[N];  
bool B[N];
queue<int>q;
void tarjan(int x){
	int y; 
    low[x]=dfn[x]=++naa;     
    s[++num]=x; B[x]=true; 
    for (int i=list[x];i;i=a[i].next){
        y=a[i].y; 
        if (!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]); 
        	else if (B[y]) low[x]=min(dfn[y],low[x]); 
    }
    if (dfn[x]==low[x])
        while (y=s[num--]){
        	belong[y]=x; 
        	B[y]=0; 
        	if (x==y) break; 
        	p[x]+=p[y]; 
        }
}
int Topology(){
	rep(i,1,n) if (belong[i]==i&&!in[i]) q.push(i),dis[i]=p[i]; 
	while (q.size()){
		int x=q.front(); q.pop();
		for(int i=head[x];i;i=b[i].next){
			int y=b[i].y; 
			dis[y]=max(dis[y],dis[x]+p[y]); 
			in[y]--; 
			if (!in[y]) q.push(y); 
		}
	}
	rep(i,1,n) sum=max(sum,dis[i]); 
	return sum; 
}
void add(int x,int y){
	b[++tot]=(node){x,y,head[x]},head[x]=tot,in[y]++;
}
int main(){
    int x,y; 
    scanf("%d%d",&n,&m); 
    rep(i,1,n) scanf("%d",&p[i]); 
    rep(i,1,m) scanf("%d%d",&x,&y),a[i]=(node){x,y,list[x]},list[x]=i; 
    rep(i,1,n) if (!dfn[i]) tarjan(i); 
    rep(i,1,m) if (belong[a[i].x]!=belong[a[i].y]) add(belong[a[i].x],belong[a[i].y]);  
    printf("%d",Topology()); 
    return 0; 
}

你可能感兴趣的:(tarjan,topology,luogu,3387,缩点)