UVA10305 Ordering Tasks (拓扑序列)

本文链接:http://www.cnblogs.com/Ash-ly/p/5398586.html

题意:

假设有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("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Ash-ly/p/5398586.html