拓扑排序——nyoj 496

1、def:对有向无环图,将G中所有节点排成一个线性序列,使得任意一对顶点a和b,如果两点之间存在边,那么在拓扑序列中a一定在b前面。

2、Algorithm:常用算法是无前驱的顶点优先的拓扑排序算法

(1)在图中找到一个无前驱的点(入度为0),其一定在拓扑序列的第一个

(2)删除掉该节点,并删除掉从该点出发的所有边,直到找到新的无前驱的点,放入序列中

(3)继续在新的的无前驱的点进行查找。

3、练习:NYOJ496

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
using namespace std;
int head[30];
int degeree[30];
struct node
{
    int from;
    int to;
    int next;
}edge[1010];
char ans[27]=
{' ','A','B','C','D','E','F','G','H',
 'I','J','K','L','M','N','O','P','Q',
 'R','S','T','U','V','W','X','Y','Z'
};

void topo(int n,int m)
{
    int i,k;
    int queue[30];
    int iq = 0;
    int flag = 1;
    int incnt = 0;

    /**********将图中入度为0的点加入队列**********/
    for(i = 1; i <= n; i++)
    {
        if(degeree[i] == 0)
        {
            queue[iq++] = i;
            incnt++;
        }
    }
    /***如果有超过一个点入度为0,则排序一定不唯一***/
    if(incnt != 1)
        flag = 0;

    /***************拓扑排序******************/
    for(i = 0; i < iq; i++)
    {
        incnt = 0;//记录删完边后入度为0的点
        /**********删除该顶点出发的所有边并更新入度**********/
        for(k = head[queue[i]]; k != -1; k = edge[k].next)
        {
            degeree[edge[k].to]--;
            if(degeree[edge[k].to] == 0)//新的没有前驱的节点
            {
                queue[iq++] = edge[k].to;
                incnt++;
            }
        }
        //对某个没有前驱的点,如果其后面找到新的没有前驱的节点超过两个,则排序不唯一
        if(incnt > 1)
        {
            flag = 0;
            break;
        }
    }
    if(!flag || iq < n)
        cout<<"No Answer"<
      
      
       
       >t1>>t2;
            edge[i].from = t1-'A'+1;
            edge[i].to = t2-'A'+1;
            degeree[t2-'A'+1]++;//注意此处是要存节点的入度

            edge[i].next = head[t1-'A'+1];
            head[t1-'A'+1] = i;
        }
        topo(n,m);
    }
}

      
      
     
     
    
    
   
   

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值