[USACO15JAN]Grass Cownoisseur G

题目传送门

神奇的解法(不同于俺的暴力算法):分层图处理,变DAG后保证第二层图,不再重复第一层图经过点(某篇洛谷题解说的)

俺的代码↓

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<stack>
using namespace std;
map<int,int> Map[100005];
int maxn=0,C=0;
int dfn[100005],low[100005],cnt=0;
stack<int> ss;
int sta[100005];
int N,N_l,N_f;
struct node{
    int to,nxt;
}a[500005],a_l[500005],a_f[500005];
int head[500005],head_l[500005],head_f[500005],c[100005],Size[100005],val[100005];
int Min(int XX,int YY){
    return XX<YY ? XX : YY;
}
int add(int XX,int YY){
    a[++N].to=YY;
    a[N].nxt=head[XX];
    head[XX]=N;
    return 0;
}
int add_l(int XX,int YY){
    a_l[++N_l].to=YY;
    a_l[N_l].nxt=head_l[XX];
    head_l[XX]=N_l;
    return 0;
}
int add_f(int XX,int YY){
    a_f[++N_f].to=YY;
    a_f[N_f].nxt=head_f[XX];
    head_f[XX]=N_f;
    return 0;
}
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<1)+(s<<3)+(ch^48);
        ch=getchar();
    }
    return s*w;
}
int Max(int AA,int BB){
    return AA > BB ? AA : BB;
}
int tarjan(int x){
    dfn[x]=low[x]=++cnt;
    ss.push(x);
    sta[x]=1;
    for(int i=head_l[x];i;i=a_l[i].nxt){//邻接表
        int y=a_l[i].to;
        if(dfn[y]==0){
            tarjan(y);
            low[x]=Min(low[x],low[y]);
        }
        else if(sta[y]==1) low[x]=Min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x]){
        int k=0;
        C++;
        while(x!=k){
            k=ss.top();
            ss.pop();
            sta[k]=0;
            c[k]=C;
            Size[C]++;
        }
    }
    return 0;
}
int dfs_f(int x,int lj){
    val[x]=Max(val[x],lj);//注意!!!
    for(int i=head_f[x];i;i=a_f[i].nxt){
        int To=a_f[i].to;
        dfs_f(To,lj+Size[To]);
    }
    return 0;
}
int dfs(int x,int lj){
    for(int i=head[x];i;i=a[i].nxt){
        int To=a[i].to;
        dfs(To,lj+Size[To]);
    }
    for(int i=head_f[x];i;i=a_f[i].nxt){
        int To=a_f[i].to;
        if(val[To]==0) continue;
        maxn=Max(maxn,lj+val[To]);
    }
    return 0;
}
int main(){
    //freopen("grass.in","r",stdin);
    //freopen("grass.out","w",stdout);
    int n=read(),m=read();
    for(int i=1;i<=m;i++){
        int XXX=read(),YYY=read();
        add_l(XXX,YYY);
    }
    for(int i=1;i<=n;i++)
        if(dfn[i]==0) tarjan(i);
    for(int i=1;i<=n;i++){
        for(int j=head_l[i];j;j=a_l[j].nxt){
            int To=a_l[j].to;
            if(c[To]==c[i]) continue;
            if(Map[c[i]][c[To]]==1) continue;
            Map[c[i]][c[To]]=1;
            add(c[i],c[To]);
            add_f(c[To],c[i]);
        }
    }
    maxn=Size[c[1]];
    dfs_f(c[1],Size[c[1]]);
    dfs(c[1],0);
    printf("%d",maxn);
    return 0;
}

 

posted @ 2021-11-11 19:38  latent_Lin  阅读(61)  评论(0)    收藏  举报