题目链接hdu1285

解题思路:裸拓扑排序 ,由于要输出字典序最小的ans,所以用堆作容器,复杂度由原来的O(V+E)变为O((V+E)*logV),题中输入的数据都符合DAG 的要求,所以不必判环。

解题细节

拓扑排序写法:

  • 初始化:将入度为0的节点V入队
  • 将入度为0的节点加入排序结果集中
  • 删除与入度为0的节点相连的边删除,相连的边入度-1
  • 将跟新边后入度为0的节点入队

AC代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <utility>
using namespace std;

const int maxn = (int)5e2+5;

int book[maxn],n,m,u,v;
vector<int> vertex[maxn]; //邻接表
priority_queue<int, vector<int>, greater<int> > Q;

int main() {
	while (~scanf("%d%d", &n,&m)) {
		for (int i = 0; i <= n; i++) { //用0下标的向量保存拓扑排序序列
			vertex[i].clear();
		}
		memset(book,0,sizeof(book));
		for (int i = 0; i < m; i++) {
			scanf("%d%d",&u,&v);
			book[v]++; // 入度+1
			vertex[u].push_back(v); //加入邻接表中
		}
		
		while(!Q.empty()) {
			Q.pop();
		}
		for (int i = 1; i <= n; i++) {
			if(book[i] == 0) {
				Q.push(i);
			}
		}
		while(!Q.empty()) {
      u = Q.top();
      Q.pop();
      vertex[0].push_back(u);
      for (vector<int>::iterator it = vertex[u].begin(); it != vertex[u].end(); it++) {
				book[*it] --;
				if(book[*it] == 0) {
					Q.push(*it);
				}
			}
		}
		
		for (vector<int>::iterator it = vertex[0].begin(); it != vertex[0].end(); it++) {
			printf("%d%c",*it," \n"[it+1 == vertex[0].end()]);
		}
	}
	return 0;
}