判斷一個有向圖是否有環

weixin_34402408發表於2018-05-10

採用深度優先遍歷

#include<iostream>
#include<malloc.h>
using namespace std;
#define maxNum 100 //定義鄰接舉證的最大定點數
int point=0;//pre和post的值
bool is_DAG=true;//標識位,表示有向無環圖
/*
頂點顏色表 color[u]
   0 白色,未被訪問過的節點標白色
   -1 灰色,已經被訪問過一次的節點標灰色
   1 黑色,當該節點的所有後代都被訪問過標黑色
反向邊:
   如果第一次訪問(u,v)時v為灰色,則(u,v)為反向邊。在對圖的深度優先搜尋中沒有發現
   反向邊,則該圖沒有迴路
程式判斷依據:
    仍然是按圖的節點深度遍歷,訪問到V時,V若被訪問過,那麼有2種狀態:
    color[u]=-1,程式跳出,存在環
    color[u]=1,程式繼續,這不是環
時間複雜度:O(n+e)
*/
int color[maxNum];//頂點顏色表 color[u]
//圖的鄰接矩陣表示結構
typedef struct
{
    char v[maxNum];//圖的頂點資訊
    int e[maxNum][maxNum];//圖的頂點資訊
    int vNum;//頂點個數
    int eNum;//邊的個數
}graph;
void createGraph(graph *g);//建立圖g
void DFS(graph *g);//深度優先遍歷圖g
void dfs(graph *g,int i);//從頂點i開始深度優先遍歷與其相鄰的點
void dfs(graph *g,int i)
{
    //cout<<"頂點"<<g->v[i]<<"已經被訪問"<<endl;
    cout<<"頂點"<<i<<"已經被訪問"<<endl;
    color[i]=-1;
    for(int j=1;j<=g->vNum;j++)
    {
        if(g->e[i][j]!=0)
        {
            if(color[j]==-1)//探索到回邊,存在環
            {
                is_DAG=false;//不是有向無環圖
            }
            else if(color[j]==0)
                dfs(g,j);
        }
    }
    color[i]=1;//表示i的後裔節點都被訪問過
}
void DFS(graph *g)
{
    int i;
    //初始化color陣列,表示一開始所有頂點都未被訪問過,//初始化pre和post
    for(i=1;i<=g->vNum;i++)
    {
        color[i]=0;
    }
    //深度優先搜尋
    for(i=1;i<=g->vNum;i++)
    {
        if(color[i]==0)//如果這個頂點為被訪問過,則從i頂點出發進行深度優先遍歷
        {
            dfs(g,i);

        }
    }
}
void createGraph(graph *g)//建立圖g
{
    cout<<"正在建立無向圖..."<<endl;
    cout<<"請輸入頂點個數vNum:";
    cin>>g->vNum;
    cout<<"請輸入邊的個數eNum:";
    cin>>g->eNum;
    int i,j;
    //初始畫圖g
    for(i=1;i<=g->vNum;i++)
        for(j=1;j<=g->vNum;j++)
            g->e[i][j]=0;
    //輸入邊的情況
    cout<<"請輸入邊的頭和尾"<<endl;
    for(int k=1;k<=g->eNum;k++)
    {
        cin>>i>>j;
        g->e[i][j]=1;
    }
}
int main()
{
    graph *g;
    g=(graph*)malloc(sizeof(graph));
    createGraph(g);//建立圖g
    DFS(g);//深度優先遍歷
    if(is_DAG)
        cout<<"圖g是有向無環圖,沒有環"<<endl;
    else
        cout<<"圖g不是有向無環圖,存在環"<<endl;
    int k;
    cin>>k;
    return 0;
}

相關文章