题意:
假设有N个变量,还有M个二元组(u, v),分别表示变量u 小于 v。那么。所有变量从小到大排列起来应该是什么样子的呢?例如,有四个变量a,b,c,d,若a < b, c < b, d < c, 则这四个变量的排序可能是a < d < c < b;尽管还有其他可能,你只需要找出其中一个即可。
思路:
把每个变量看成一个点,“小于”看成一个边,则得到一个有向图。这样,实际任务就是把一个图的所有节点排序,使得对应的每一条有向边(u, v),对应的u都排在v前面,即就是拓扑排序。
代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <stack> #include <algorithm> using namespace std; const int maxV = 100; int head[maxV + 7]; int n, m; queue<int> ansQu; struct EdgeNode{ int to; int next; }Edges[maxV * maxV + 7]; int indegree[maxV]; void getIdg()//获得入度 { memset(indegree, 0, sizeof(indegree)); for(int i = 1; i <= m; i++) indegree[ Edges[i].to ]++; } void tplgSort()//拓扑排序 { getIdg(); stack<int> tpst; for(int i = 1; i <= n; i++) if(!indegree[i]) tpst.push(i); while(!tpst.empty()) { int v = tpst.top(); ansQu.push(v); tpst.pop(); for(int j = head[v]; j != -1; j = Edges[j].next) if(!(--indegree[ Edges[j].to ])) tpst.push(Edges[j].to); } } int main() { while(~scanf("%d%d", &n ,&m) && (n || m)) { memset(head, -1, sizeof(head)); memset(&Edges, 0, sizeof(EdgeNode)); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d",&u, &v); Edges[i].to = v; Edges[i].next = head[u]; head[u] = i; } tplgSort(); int flag = 0; while(!ansQu.empty()) { printf(flag++ ? " %d":"%d", ansQu.front()); ansQu.pop(); } printf("\n"); } return 0; }
时间: 2024-11-05 19:36:18