SDNU 1089.拓扑排序(拓扑判环小顶堆)

Posted rootvount

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDNU 1089.拓扑排序(拓扑判环小顶堆)相关的知识,希望对你有一定的参考价值。

Description

给定一个有向图,若图无环,则将其进行拓扑排序并输出,否则输出IMPOSABLE。

Input

第一行为两个整数n(1<=n<=1000)、m(1<=m<=100000);
之后m行,每行两个整数a、b(0 < a, b <= n)表示一条从a到b的有向边。

Output

若存在环,输出IMPOSABLE,否则输出一行用一个空格隔开的拓扑排序的结果,若存在多个结果,输出字典序最小的。

Sample Input

5 4
1 2
2 3
3 4
4 5

Sample Output

1 2 3 4 5

Source

Unknown
#include<bits/stdc++.h>
using namespace std;

int n, m, a, b, d[1000+8], num, cnt;
vector<int>t[1000+8];
queue<int>q;
int ans[1000+8], sign[1000+8];
bool flag = 0;
priority_queue<int, vector<int>, greater<int> >you;

void bfs()
{
    while(!you.empty())
    {
        int f = you.top();
        you.pop();
        if(flag)printf(" ");
        flag = 1;
        printf("%d", f);
        for(int i = 0; i<t[f].size(); i++)
        {
            d[t[f][i]]--;
            if(d[t[f][i]] == 0 && !sign[t[f][i]])
            {
                you.push(t[f][i]);
                sign[t[f][i]] = 1;
            }
//            }
        }
    }
}

int get(int miao)//判环
{
    int in[1000+8],si[1000+8];
    for(int i = 0; i <= miao; i++)
    {
        in[i] = d[i];
        si[i] = sign[i];
    }
    num = miao;
    while(!q.empty())
    {
        int f = q.front();
        num--;
        q.pop();
        for(int i = 0; i<t[f].size(); i++)
        {
            in[t[f][i]]--;
            if(!in[t[f][i]] && !si[t[f][i]])
            {
                q.push(t[f][i]);
                si[t[f][i]] = 1;
            }
        }
    }
    return num;
}

int main()
{
    while(~scanf("%d%d", &n, &m) && (n+m))
    {
        memset(d, 0, sizeof(d));
        memset(sign, 0, sizeof(sign));
        for(int i = 0; i<1000+8; i++)t[i].clear();
        while(!q.empty())q.pop();
        for(int i = 0; i<m; i++)
        {
            scanf("%d%d", &a, &b);
            t[a].push_back(b);//存图
            d[b]++;//入度++
        }
        for(int i = 1; i <= n; i++)
        {
            if(!d[i] && !sign[i])//查找入度为0的节点,再插入队列,并标记它用过了
            {
                q.push(i);
                you.push(i);
                sign[i] = 1;
            }
        }
        if(get(n) == 0)//如果不存在环
        {
            bfs();//用bfs输出结果
        }
        else printf("IMPOSABLE\n");
    }
    return 0;
}

 

以上是关于SDNU 1089.拓扑排序(拓扑判环小顶堆)的主要内容,如果未能解决你的问题,请参考以下文章

oj---poj4084----拓扑排序

拓扑排序判环

[hiho1174]拓扑排序一(拓扑排序判环)

Codeforces915 D. Almost Acyclic Graph(思维,拓扑排序原理,拓扑排序判环)

POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)

HDU1811 拓扑排序判环+并查集