洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur

 

屠龙宝刀点击就送

Tarjan缩点+拓扑排序

以后缩点后建图看n范围用vector ,或者直接用map+vector

结构体里数据要清空

代码:

#include <cstring>
#include <cctype>
#include <cstdio>
#include <vector>
#include <queue>
#define N 100005
using namespace std;
vector<int>G[N];
inline void Read(int &x)
{
    register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
}
bool instack[N];
int n,m,ans,stack[N],low[N],dfn[N],col[N],sum[N],f1[N],f2[N],in1[N],in2[N],sumcol,tim,top;
inline int min(int a,int b) {return a>b?b:a;}
inline int max(int a,int b) {return a>b?a:b;}
void tarjan(int x)
{
    low[x]=dfn[x]=++tim;
    stack[++top]=x;
    instack[x]=true;
    for(int i=0;i<G[x].size();++i)
    {
        int v=G[x][i];
        if(!dfn[v])
        {
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if(instack[v]) low[x]=min(low[x],dfn[v]);
    }
    if(low[x]==dfn[x])
    {
        int k;
        sumcol++;
        do
        {
            k=stack[top--];
            instack[k]=false;
            col[k]=sumcol;
            sum[sumcol]++;
        }while(k!=x);
    }
}
struct node
{
    int f[N],in[N],cnt;
    struct Edge
    {
        int to;
        Edge * next;
    }*head[N],edge[N];
    void ins(int u,int v)
    {
        in[v]++;
        edge[++cnt].next=head[u];
        edge[cnt].to=v;
        head[u]=cnt+edge; 
    }
    void tppx()
    {
        queue<int>q;
        for(int i=1;i<=sumcol;++i) {f[i]=0xefefefef;if(!in[i]) q.push(i);} 
        f[col[1]]=sum[col[1]];
        for(int now;!q.empty();)
        {
            now=q.front();
            q.pop();
            for(Edge * u=head[now];u;u=u->next)
            {
                int v=u->to;
                f[v]=max(f[v],f[now]+sum[v]);
                in[v]--;
                if(!in[v]) q.push(v); 
            }
        }
    }
    node ()
    {
        cnt=0;
        memset(in,0,sizeof(in));
        memset(head,NULL,sizeof(head));
    }
};
node a,b;
int main()
{
    Read(n);
    Read(m);
    for(int x,y;m--;)
    {
        Read(x);
        Read(y);
        G[x].push_back(y);
    }
    for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;++i)
    {
        for(int j=0;j<G[i].size();++j)
        {
            int v=G[i][j];
            if(col[i]!=col[v]) a.ins(col[i],col[v]),b.ins(col[v],col[i]);
        }
    }
    a.tppx();
    b.tppx();
    ans=sum[col[1]];
    for(int i=1;i<=n;++i)
    {
        for(int j=0;j<G[i].size();++j)
        {
            int v=G[i][j];
            ans=max(ans,a.f[col[v]]+b.f[col[i]]);
        }
    }
    printf("%d\n",ans-sum[col[1]]);
    return 0;
}

 

posted @ 2017-09-05 21:59  杀猪状元  阅读(198)  评论(0编辑  收藏  举报