拓扑排序:

拓扑排序是应用于有向无回路图(DAG)上的一种排序方式,对一个有向无回路进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u在v的前面。该序列说明了顶点表示的事件或 状态发生的整体顺序。

比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时可以以工程为顶点,工程间的依赖关系为边建立图,用拓扑排序来求得所有工程的合理执行顺序。

对一个DAG进行拓扑排序有两种方法,广度优先搜索和深度优先搜索

这里介绍广度优先搜索,进行拓扑排序时,每次可以拿出的顶点一定是入度为0的点,即没有被指向的点,因为这样的点表示的事件没有依赖,在一个入度为0的点表示的事件执行完之后,它所指向的顶点所依赖的点就少了一个,所以我们可以先将所有入度为0的点加入一个队列中,然后依次将它们所指向的点的入度减1,再将入度变为0的点也依次加入队列中,这样最后就可以得到一个拓扑有序的序列。

本题中说符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前,需要用到优先队列,每次从队列中取的是最小的那个元素

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int maxn=;
int graph[maxn][maxn];//保存图
int degree[maxn];//保存入度 int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(graph,,sizeof(graph));
memset(degree,,sizeof(degree));
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(!graph[u][v])
{
graph[u][v]=;
degree[v]++;//v的入度++
}
}
priority_queue<int,vector<int>,greater<int> >q;
for(int i=;i<=n;i++)
if(degree[i]==)
q.push(i);
bool first=;
while(!q.empty())
{
int cur=q.top();
q.pop();
if(first)
{
cout<<cur;
first=;
}
else
cout<<" "<<cur;
for(int i=;i<=n;i++)
{
if(graph[cur][i])
{
degree[i]--;//相连的点的入度减1
if(degree[i]==)//如果入度为0,加入队列
q.push(i);
}
}
}
printf("\n");
}
return ;
}
/**
* The Kahn's Topological Sort Algorithm in C++
* Using the Adjecency List
* Time Cost : O(|V|+|E|)
* Author: Zheng Chen / Arclabs001
* Copyright 2015 Xi'an University of Posts & Telecommunications
*/
#include <iostream>
#include <queue>
#include <vector>
using namespace std; const int N = ; // The number of Vertex enum status {UNDISCOVERED,VISITED}; struct Vertex
{
int inDegree, outDegree;
int data;
status _stat;
}V[N]; vector<int> AdjList[N]; //Using vector to simulate the adjlist
queue<int> vertexQueue; //The call queue
/**
* Initialize the graph as below:
The Graph: 0->1->3
| | |
\/ \/ \/
2->4<-- * @return The pointer to the start vertex
*/
Vertex* init_graph()
{
while(!vertexQueue.empty())
vertexQueue.pop(); for(int i=; i<N; i++)
{
AdjList[i].clear();
V[i]._stat = UNDISCOVERED;
V[i].data = i;
} V[].inDegree = ; V[].outDegree = ;
V[].inDegree = ; V[].outDegree = ;
V[].inDegree = ; V[].outDegree = ;
V[].inDegree = ; V[].outDegree = ;
V[].inDegree = ; V[].outDegree = ; AdjList[].push_back(); AdjList[].push_back();
AdjList[].push_back(); AdjList[].push_back();
AdjList[].push_back();
AdjList[].push_back(); return & V[];
} bool Topological_Sort()
{
for(int i=; i<N; i++)
{
if(V[i].inDegree == )
vertexQueue.push(i);
} while(!vertexQueue.empty())
{
int top = vertexQueue.front();
V[top].outDegree = ;
V[top]._stat = VISITED;
int i=; for(int v : AdjList[top])
{
--V[v].inDegree; AdjList[top][i++] = -;
if(V[v].inDegree == )
vertexQueue.push(v);
}
cout<<top<<" "; vertexQueue.pop();
} for(int i=; i<N; i++)
{
for(int v : AdjList[i])
if(v != -)
{
return false;
}
} return true;
} int main()
{
init_graph(); bool status = Topological_Sort();
if(status == false)
{
cout<<"Error! The graph has at least one cycle!"<<endl;
}
return ;
}

HDU1285 裸的拓扑排序的更多相关文章

  1. HDU1285 确定名次 拓扑排序

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

  2. POJ 2367 (裸拓扑排序)

    http://poj.org/problem?id=2367 题意:给你n个数,从第一个数到第n个数,每一行的数字代表排在这个行数的后面的数字,直到0. 这是一个特别裸的拓扑排序的一个题目,拓扑排序我 ...

  3. hdu1285+hdu2467(拓扑排序)

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  4. 拓扑排序 POJ2367Genealogical tree[topo-sort]

    ---恢复内容开始--- Genealogical tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4875   A ...

  5. 拓扑排序--UVa10305

    题目 Output: standard output Time Limit: 1 second Memory Limit: 32 MB John has n tasks to do. Unfortun ...

  6. UVA10305 拓扑排序

    网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=117863#problem/B 思路分析:裸的拓扑排序,注释在代码中. 代码: #i ...

  7. [poj2585]Window Pains_拓扑排序

    Window Pains poj-2585 题目大意:给出一个4*4的方格表,由9种数字组成.其中,每一种数字只会出现在特定的位置,后出现的数字会覆盖之前在当前方格表内出现的.询问当前给出的方格表是否 ...

  8. CF-825E Minimal Labels 反向拓扑排序

    http://codeforces.com/contest/825/problem/E 一道裸的拓扑排序题.为什么需要反向拓扑排序呢?因为一条大下标指向小下标的边可能会导致小下标更晚分配到号码,导致字 ...

  9. 拓扑排序 Topological Sort

    2018-05-02 16:26:07 在计算机科学领域,有向图的拓扑排序或拓扑排序是其顶点的线性排序,使得对于从顶点u到顶点v的每个有向边uv,u在排序中都在v前.例如,图形的顶点可以表示要执行的任 ...

随机推荐

  1. 一行代码搞定checkbox全选和全不选

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  2. php结合redis实现高并发下的抢购、秒杀功能【转】

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  3. Linux编译移植Qt4的环境_在OMAPL138平台

    Linux编译Qt4的环境_OMAPL138 手里有一块创龙OMAPL138的板子,我要在上面成功移植Qt环境和触摸屏幕,这是我第二次进行Linux的Qt环境移植,发现了很多问题,需要重新整理. 我编 ...

  4. POJ 3581 三段字符串(后缀数组)

    Sequence Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7923   Accepted: 1801 Case Tim ...

  5. DFS:C 小Y的难题(1)

    解题心得: 1.在明确使用DFS之后一定要找到递归函数的出口.方向,以及递归的点(在某个情况下开始递归)(void 也可以return,但是没有返回值).递归时也要有递归的方向,最后都能够达到递归的出 ...

  6. [Bzoj2286]消耗战(虚树+DP)

    Description 题目链接 Solution 在虚树上跑DP即可 Code #include <cstdio> #include <algorithm> #include ...

  7. cf978E Bus Video System

    The busses in Berland are equipped with a video surveillance system. The system records information ...

  8. 7.Mongodb安全性流程

    1.安全性流程 2.超级管理员 为了更安全的访问mongodb,需要访问者提供用户名和密码,于是需要在mongodb中创建用户 采用了角色-用户-数据库的安全管理方式 常用系统角色如下: root:只 ...

  9. 静态html引入js添加随机数后缀防止缓存

    在web项目开发中,页面引入js被修改时,为避免浏览器缓存引起的问题,在引入js时,给js名后面加上随机数,以保证每次都发送新的请求. 在jsp中,一般通过后台取随机数即可,代码如下: <scr ...

  10. 剑指Offer - 九度1214 - 丑数

    剑指Offer - 九度1214 - 丑数2013-11-21 21:06 题目描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. ...