LA 4287(p322)----Proving Equivalences

#include<bits/stdc++.h>
#define debu
using namespace std;
const int maxn=1e5+50;
int s[maxn];
int v[maxn];
int dfn[maxn];
int scc[maxn];
int low[maxn];
int sum1,sum2;
int n,m,all,top,num;
int din[maxn],dout[maxn];
vector<int> g[maxn];
void init()
{
    all=0;
    top=0;
    num=0;
    sum1=0;
    sum2=0;
    memset(s,0,sizeof(s));
    memset(v,0,sizeof(v));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(scc,0,sizeof(scc));
    for(int i=0; i<=n; i++) g[i].clear();
}
void Find(int u)
{
    all++;
    dfn[u]=all;
    low[u]=all;
    top++;
    s[top]=u;
    v[u]=true;
    for(int i=0; i<g[u].size(); i++)
    {
        int j=g[u][i];
        if(dfn[j]==0)
        {
            Find(j);
            low[u]=min(low[u],low[j]);
        }
        else
        {
            if(v[j])
                low[u]=min(low[u],dfn[j]);
        }
    }
    if(low[u]==dfn[u])
    {
        num++;
        while(s[top+1]!=u)
        {
            scc[s[top]]=num;
            v[s[top]]=false;
            top--;
        }
    }
}
void make()
{
    for(int i=1; i<=n; i++)
        if(dfn[i]==0) Find(i);
}
void solve()
{
    memset(din,0,sizeof(din));
    memset(dout,0,sizeof(dout));
    for(int u=1; u<=n; u++)
        for(int j=0; j<g[u].size(); j++)
        {
            int v=g[u][j];
            if(scc[u]!=scc[v])
            {
                dout[scc[u]]=1;
                din[scc[v]]=1;
            }
        }
    for(int i=1; i<=num; i++)
    {
        if(!din[i]) sum1++;
        if(!dout[i]) sum2++;
    }
    int ans=(num!=1)?max(sum1,sum2):0;
    printf("%d\n",ans);
}
int main()
{
#ifdef debug
    freopen("in.in","r",stdin);
#endif // debug
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d%d",&n,&m);
        for(int i=0; i<m; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
        }
        make();
        solve();
    }
    return 0;
}

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2288

题解:Tarjan求强连通分量后缩点,设缩点后DAG图中入度为0点个数为sum1,出度为0点个数为sum2,则ans=max(sum1,sum2)(注意当原图已经强连通时,ans=0)。

你可能感兴趣的:(LA 4287(p322)----Proving Equivalences)