拓扑排序

DAG(有向无环图)才有拓扑序列(有向无环图中的所有的路线必须都是单向的)
拓扑序列指,若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。
acwing—奖金(拓扑排序)

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//拓扑排序中,如果无法把n个点全部加入到q中,则代表没有top序
//因为每个点只会被加入1次,统计加入的次数和所有的点数进行对比即可

const int N=2e4+10;

int idx,h[N],ne[N],e[N],hh,tt=-1,q[N];
int n,m,d[N];//i的入度是多少。
bool st[N];//不需要st数组

int dist[N];

void add(int a,int b)
{
    e[idx]=b;ne[idx]=h[a],h[a]=idx++;
}

long long  topsort()
{

    for(int i=1;i<=n;i++)
    {
        if(!d[i])
        {
            q[++tt]=i;
        }
    }

    while(hh<=tt)
    {
        int t=q[hh++];

        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(!d[j])
            {
                q[++tt]=j;
            }
        }
    }
    return tt==n-1;//tt最后就是队列中所有的元素个数-1,如果有点无法加入队列代表该点的入度无法为0,即存在环
}

int main()
{
    memset(h,-1,sizeof h);
    cin>>n>>m;
    while(m--)
    {
        int a,b;cin>>a>>b;
        add(b,a);
        d[a]++;
    }
    int t=topsort();
    if(!t)
    {
     cout<<"Poor Xed"<<endl;
    }
    else
    {
        for (int i = 1; i <= n; i ++ ) dist[i] = 100;
        for (int i = 0; i < n; i ++ )
        {
            int j = q[i];
            for (int k = h[j]; ~k; k = ne[k])
                dist[e[k]] = max(dist[e[k]], dist[j] + 1);
        }

        int res = 0;
        for (int i = 1; i <= n; i ++ ) res += dist[i];

        printf("%d\n", res);

    }
    return 0;
}
posted @ 2020-09-30 16:29  30天CF上蓝!!!  阅读(90)  评论(0编辑  收藏  举报