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;
}

原文地址:https://www.cnblogs.com/RootVount/p/10828022.html

时间: 2024-12-10 17:39:07

SDNU 1089.拓扑排序(拓扑判环小顶堆)的相关文章

POJ3253 Fence Repair 小顶堆+贪心

给了你N个木棒,求把他们组装成一根需要的最小花费,每次只能选两根组装在一起,需要的花费为两个木棒之和, 以前遇到过把一整根切开的,那个是DP,这个则有些类似,可是大胆的猜测了一下,直接每次选取所有木棒中最短的两根,这样就可以了,那么贪心是适用的,但是数量很多,而且两根最短的组装好了得插回去,这样不可能每次都排序吧, 这题首先优先队列肯定是可以做的, 最小堆也是可以的,每次都选出堆里的最小的两个求和再放回去即可 队列本身也就是堆吧,所以差别不大,但是没用过最小堆最大堆的 所以用一次把 #inclu

wikioi 2573 大顶堆与小顶堆并用

题目描述 Description 我们使用黑匣子的一个简单模型.它能存放一个整数序列和一个特别的变量i.在初始时刻,黑匣子为空且i等于0.这个黑匣子能执行一系列的命令.有两类命令: ADD(x):把元素x放入黑匣子:GET:把i加1的同时,输出黑匣子内所有整数中第i小的数.牢记第i小的数是当黑匣子中的元素已非降序排序后位于第i位的元素. 下面的表6_4是一个11个命令的例子: 表6_4 编号 命令 i 黑匣子内容 输出 1 ADD(3) 0 3 2 GET 1 3 3 3 ADD(1) 1 1,

剑指offer:数据流中的中位数(小顶堆+大顶堆)

1. 题目描述 /** 如何得到一个数据流中的中位数? 如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值. 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 我们使用 Insert()方法读取数据流,使用 GetMedian()方法获取当前读取数据的中位数. */ 2. 思路 /** 最大堆和最小堆 * 每次插入小顶堆的是当前大顶堆中最大的数 * 每次插入大顶堆的是当前小顶堆中最小的数 * 这样保证小顶堆中的数永远大于等于大顶堆中的数(值

wikioi 1245 小顶堆

题目描述 Description 有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求这N^2 个和中最小的 N个. 输入描述 Input Description 第一行输入一个正整数N:第二行N个整数Ai 且Ai≤10^9:第三行N个整数Bi, 且Bi≤10^9 输出描述 Output Description 输出仅一行,包含 n 个整数,从小到大输出这 N个最小的和,相邻数字之间用 空格隔开. 样例输入 Sample Input 5 1 3 2 4

heap c++ 操作 大顶堆、小顶堆

在C++中,虽然堆不像 vector, set 之类的有已经实现的数据结构,但是在 algorithm.h 中实现了一些相关的模板函数.下面是一些示例应用 http://www.cplusplus.com/reference/algorithm/pop_heap/ #include <iostream> #include <algorithm> // make_heap(), pop_heap(), push_heap() #include <vector> using

python 大顶堆 小顶堆

http://www.coder4.com/archives/3844 需1求:给出N长的序列,求出TopK大的元素,使用小顶堆,heapq模块实现. import heapq import random class TopkHeap(object): def __init__(self, k): self.k = k self.data = [] def Push(self, elem): if len(self.data) < self.k: heapq.heappush(self.data

BZoj 1293 生日礼物(小顶堆)

传送门:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27400 Anayse:小顶堆: 1 1 5     - >    1 3 5     ->    3 5 7    ->     5 7 8 pop(1)    p(1)      p(3)       最优解. 每次剔除堆顶,然后换push与堆顶相同种类的珠子,由于单调,,距离会被缩短,于是找出最优解.详见上式. push()  log(n) so,复杂度

优先级队列(小顶堆)的dijkstra算法

php实现迪杰斯特拉算法,并由小顶堆优化 1 <?php 2 3 class DEdge 4 { 5 public $nextIndex, $length; 6 7 public function __construct($nextIndex, $length) 8 { 9 $this->nextIndex = $nextIndex; 10 $this->length = $length; 11 } 12 } 13 14 class DNode 15 { 16 public $index

7-31 笛卡尔树 (25分)--判断二叉搜索树,小顶堆

先初步判断是否满足二叉搜索树和小顶堆(针对每一颗最小的子树),如果都满足,进一步判断整棵树是否满足. 1 #include <iostream> 2 #include <string> 3 #include <cstring> 4 using namespace std; 5 typedef struct node 6 { 7 int K1; 8 int K2; 9 int L; 10 int R; 11 }node_arr[1001]; 12 node_arr s;