拓扑排序(链表实现,未测试)

文章作者:ktyanny 文章来源:ktyanny 转载请注明,谢谢合作。     

  

  一直是在用邻接表,有时候想尝试用链表来处理图的算法,也许能够找到喜感。呵呵,今晚了解了这个心愿吧。

  话说好久没有努力学习了,但是我还是很努力去谈恋爱的^.^。年前年后,算算应该是有2个月左右没有碰了吧,现在赶紧努力起来。像老公说的那样,把之前的东西捡一捡,在没有把遗留下来的问题先解决掉,这样学起来也不会那么辛苦了。他还告诉我,如果你没有把你之前学过的知识忘掉,那么你就已经是一个天才了。好吧。不会让你担心失望的。

  贴上我今晚的学习结果吧。没有测试的版本:

  

#include  < iostream >
#include 
< stack >
#include 
< stdio.h >
using   namespace  std;

// n 为图G的顶点个数
int  n;

// 定义邻接表的结构,一个结构记录一条边
struct  Edge
{
    
int  dest;  // 记录的地
     int  value;  // 边的权值
    Edge *  next;
};

// 申请表空间
Edge *  edge  =   new  Edge[n]; // 在这里使用new,因为n是可变的
int  i, u, v;

// 初始化邻接表
void  init()
{
    
for ( int  i  =   0 ; i  <  n; i ++ )
        edge[i].next 
=  NULL;
}

void  read()
{
    Edge
*  l;
    
// 接受输入,(u,v)代表一条边
     int  u, v;
    
while (cin  >>  u  >>  v)
    {        
        l 
=   new  Edge;     //  新建一个邻接表结构    
        l -> dest  =  v; // 填写目的地位顶点v
        
// 把新建的邻接表结构加入到顶点u的链表中去
        l -> next  =  edge[u].next;
        edge[u].next 
=  l;

        
// 如果是有向图的话,下面4句话可以省略
        l  =   new  Edge;
        l
-> dest  =  u;
        l
-> next  =  edge[v].next;
        edge[v].next 
=  l;                
    }
}

int  ret[ 1005 ];
int  linktoposort()
{
    
// 统计每个顶点的入度数
     int *  degree  =   new   int [n];
    memset(degree, 
0 , n * sizeof ( int ));
    
int  i;
    Edge
*  l;
    
for ( int  i  =   0 ; i  <  n; i ++ )
    {
        l 
=  edge[i].next;
        
while (l)
        {
            degree[l
-> dest] ++ ;
            l 
=  l -> next;
        }
    }
    stack
< int >  s;
    
for ( int  i  =   0 ; i  <  n; i ++ )
    {
        
if (degree[i]  ==   0 )
            s.push(i);
    }
    
int  count  =   0 ;
    
int  u;
    
while ( ! s.empty())
    {
        u 
=  s.top();
        s.pop();
        ret[count] 
=  u;
        count
++ ;
        
        l 
=  edge[u].next;
        
while (l)
        {
            degree[l
-> dest] -- ;
            
if (l -> dest  ==   0 )
                s.push(l
-> dest);
            l 
=  l -> next;
        }
    }
    
if (count  ==  n)
        
return   1 ;
    
return   0 ;
}

int  main()
{
    init();
    read();
    linktoposort();
    
return   0 ;
}

有空的话做一下:poj 1094 3267 3687 2367 3272

        HDoj 1285 

        zoj 1060 1083

好吧,先这样了。

 

转载于:https://www.cnblogs.com/ktyanny/archive/2010/03/03/1677631.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值