soj 1075 拓扑排序队列实现

就是soj 拓扑排序的模板题吧。然后我中午把用队列实现的拓扑排序的方法看了下。晚上就打算来练一下这种纯模板。

对于这实现的方法,我的理解就是存下每个节点的入度以及它指向的其他节点,由于指向多少个这个不太能确定所以用一个vector来存。然后将入度为零的节点取出来入队列,再将其所指向的节点之间的边都删掉(也就是将所指向的节点的入度减1)减掉之后如果这个点变为入度为0了,就可以将其入队了。。还有关于输出的问题就是每次从队列中取出一个出来,那么这个就是此时的节点,就可以将它输出了。

大概就是这样的吧,我也不知道自己理解错了没有。

给个别人写的拓扑排序的原理及实现吧,http://www.2cto.com/kf/201308/233520.html

对于这道题来说:题目中指明了每个输入只有对应一种输出,并且不可能没有输出,所以我们连判断有没有环都不需要了。

背景:我一开始写错了,连没有输入的字母都出现了,后来加了个数组用于标记这个字母是否出现才解决了这个问题。还有就是要注意格式的控制,而且对于每一个vector都要进行初始化。其他应该没有什么了毕竟第一道拓扑排序,就是模板题啊。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define M 100
int s[M];  //来记录每个字母的入度
vector<int> G[M];  //用vector来存储当前这个点所指向的各个点
int mark[M];      //标记这个字母是否在输入之中
int n;
void topo()
{
    queue<int> q;
    int first = 1;
    for(int i = 0;i < 26;i++)
        if(!s[i]&&mark[i])
        q.push(i);
    while(!q.empty())
    {
        int t = q.front();
        q.pop();
        if(first) printf("%c",t+'A');   //如果是第一次就不需要前面的空格
        else printf(" %c",t+'A');
        first = 0;
        for(int i = 0;i < G[t].size();i++)
        {
            s[G[t][i]]--;
            if(s[G[t][i]]==0)
                q.push(G[t][i]);
        }
    }
}
int main()
{
    while(scanf("%d",&n)==1 && n)
    {
        memset(mark,0,sizeof(mark));
        for(int i = 0;i < 26;i++)
            G[i].clear();  //要对每一个vector进行初始化,不然不同组之间会相互影响
        for(int i = 0;i < n;i++)
        {
            char a,b;
            cin >> a >> b;
            mark[a-'A'] = 1;
            mark[b-'A'] = 1;
            s[b-'A']++;
            G[a-'A'].push_back(b-'A');
        }
        topo();
        printf("\n");
    }
    return 0;
}

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/liujc_/article/details/44682599
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞