拓扑排序

//拓扑排序关键在于一个入度,首先说明入度的作用,这就好比学科A,入度就是到这门学科的边的条数,如果到这门学科为0了,就说明不需要先学什么
//那么自然就要学习这门学科,然后再将与这门学科相连的其他学科的入度减一,因为他们原来入度(即边的条数包含A学科到自己的边,现在A学科学过了,自然少了一个障碍,
//而如果此时正好该门学科入度变成0了,那么又可以学习该门学科~~
//入度的求法:从上文可以看出入度就是到该点的边的条数,那么只需要在读入时边读,边让终点的入度加一即可~~(因为是有向图嘛)
//这里还需注意如果是含有回路,那么就会出错,因为你不可能先学高数,再学离散数学,(高数->离散)结果发现离散还要以高数为基础(离散->高数)...
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
queue<int>q;
int main()
 {
     int n,m,c,d,count,i,j;
    int a[101][101];
    int ans[101];
    int indegree[101];
     scanf("%d%d",&n,&m);
     for (i=1;i<=n;i++)
        indegree[i]=0;
        for (i=1;i<=n;i++)
            for (j=1;j<=n;j++)
            a[i][j]=0;
        for (i=1;i<=m;i++)
           {
            scanf("%d%d",&c,&d);
            a[c][d]=1;
            indegree[d]++;//到d的点边又多了一条(即入度加一)
           }
           count=0;
          for (i=1;i<n;i++)
              if (!indegree[i])
              {
                q.push(i);//找寻入度为0的点
               ans[++count]=i;
              }//先将所有入度为0的点入栈,同时记录下节点
              while(!q.empty())
              {
                 int  temp=q.front();
                  q.pop();
                 for (i=1;i<=n;i++)
                    if (a[temp][i])//和i边相连
                    {
                    indegree[i]--;//i边入度减一
                     if (!indegree[i])//如果减过之后发现i边的入度减少为0,那么就将其入栈
                     {
                        q.push(i);
                        ans[++count]=i;//保存路径
                    }
                    }
              }

              if (count<n) printf("含有回路\n");//为什么count<n时就含有回路,比如三角形1->2,2->3,3->1那么可以看出每一个点的入度都是1,也就是外面的图形永远无法访问到首位相连的里面的图形,所以ocunt一定会小于n.
             else
                for (i=1;i<=n;i++)//否则输出保存的路径
                printf("%d ",ans[i]);
                printf("\n");
              return 0;

    }


 


例如下面两图


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值