通俗易懂的有向图无向图有环没环

有向图,

先进行拓补排序,若数组中个数等于n则无环 否则有环

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
vector<int>e[1005];
int out[1005];
void topsort( int  n )
{


    int  i;
    int a[1005];
    priority_queue<int>q;
    for( i = 1; i<=n; i++)
    {
        if( out[i] == 0 )
            q.push( i );
    }
    int k = 0;
    while( !q.empty())
    {
        int s = q.top();
        a[k++] = s;
        q.pop();
        for( i =0; i<e[s].size(); i++)
        {
            out[e[s][i]]--;
            if( out[e[s][i]] == 0)
                q.push( e[s][i] );
        }
    }
    if( n == k )
        {
            for( i =k-1; i>0 ;i--)
            {
                printf("%d ", a[i]);
            }
            printf("%d\n", a[0]);
        }
    else
        printf("IMPOSABLE\n");


}
int main()
{
    int n, m, i;
    while(scanf("%d%d", &n, &m) != EOF )
  {
        for( i =1; i<=n; i++)
    {
        out[i] = 0;
        e[i].clear();
    }
    int a,b;
    for( i =0; i<m; i++)
    {
        scanf("%d%d", &a, &b );
        e[b].push_back( a );
        out[a]++;
    }
    topsort( n );
  }
    return 0;

}

无向图

无向图中当顶点的数量和边的数量很大的时候,使用dfs存在大量的递归,会导致栈溢出。使用下面的方法可以有效的避免。

判断无向图中是否存在回路(环)的算法描述

如果存在回路,则必存在一个子图,是一个环路。环路中所有顶点的度>=2

算法:

     第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。

     第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。

     如果最后还有未删除顶点,则存在环,否则没有环。

算法分析:

            由于有m条边,n个顶点。如果m>=n,则根据图论知识可直接判断存在环路。

    (证明:如果没有环路,则该图必然是k棵树 k>=1。根据树的性质,边的数目m = n-k。k>=1,所以:m<n)

            如果m<n 则按照上面的算法每删除一个度为0的顶点操作一次(最多n次),或每删除一个度为1的顶点(同时删一条边)操作一次(最多m次)。这两种操作的总数不会超过m+n。由于m<n,所以算法复杂度为O(n)



  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值