算法——判断无向图是否含有回路

1.并查集——存疑无法实现

2.DFS——存疑无法实现

3.剪枝法

剪枝法思路:

1.如果存在环,那么环中所有节点的度是大于等于2的

2.根据图论,如果无向图弧的个数大于等于节点个数,那么图必定存在环

3.把度小于2的点全部删除,并且删除与此节点相关的弧,再统计剩下节点度小于2的点,再把这些点删除,同时删除与此节点相关的弧,直到最后,形成环的节点是不会被删除的,所以如果结束后,删除节点个数小于总结点个数,那么有环,否则无环

4.整个算法借助栈来实现,并使用一个标记数组来表示节点的被删除状态,用相邻节点的度减一来模拟与节点的弧的删除

#include
#include
#include
#include
using namespace std;
//并查集
class union_set
{
private:
    vectorparents;
public:
    union_set(int len);
    int find_parents(int index);
    void make_union(int index1,int index2);
};
union_set::union_set(int len)
{
    int i;
    for(i=0;iVerNode_List;
    vectorVisited_Mark;
    vectorcolor;//节点的颜色标记,-1代表没有访问,0代表正在访问,1代表访问结束
    int line;//弧的个数
    int node;//节点的个数
public:
    Adjacency_List() {}
    void create(const vectordata,const int Road_Nums);
    void output();
    void Reset_mark();
    bool Cycle_or_not();//剪枝法判断此无向图是否有环成功
    //void DFS_Cycle(bool&flag,const int u);//深度优先遍历判断无向图是否有环————存疑,无法实现
    //bool use_unionset_cycle_or_not();//使用并查集判断无向图是否有环————同样存疑,无法实现
    ~Adjacency_List();
};
void Adjacency_List::create(const vectordata,const int Road_Nums)
{
    line=Road_Nums;
    node=data.size();
    VerNode*Node_Pointer_temp;
    ArcNode*Arc_Pointer;
    int i,j,k,weight;
    int Data_Len=data.size();
    cout<<"请输入"<>i;
        cin>>j;
        //不用担心弧被重复计数的情况,检查函数会把他排除
        Arc_Pointer=new ArcNode(j,VerNode_List[i]->First_Edge);
        VerNode_List[i]->First_Edge=Arc_Pointer;
        VerNode_List[i]->du++;
        Arc_Pointer=new ArcNode(i,VerNode_List[j]->First_Edge);
        VerNode_List[j]->First_Edge=Arc_Pointer;
        VerNode_List[j]->du++;
    }
}
void Adjacency_List::output()
{
    ArcNode*s;
    int i;
    for(i=0; iVervex;
        cout<<" 当前节点的度是 "<du<<" ";
        s=VerNode_List[i]->First_Edge;
        while(s!=nullptr)
        {
            cout<<"——————"<Adjvex;
            s=s->next;
        }
        cout<First_Edge;
        delete VerNode_List[i];
        while(s!=nullptr)
        {
            q=s;
            s=s->next;
            delete q;
        }
    }
}
bool Adjacency_List::Cycle_or_not()
{
    stacks;
    if(line>=node)//根据图论知识,如果弧的个数大于节点的个数,那么该图一定有环
        return true;
    int i,idx,num=0;
    int k;
    ArcNode*p;
    for(i=0; idu<2)//把所有的度小于2的节点入栈,因为在环中的
            s.push(i);
    }
    //由于在下列循环中,无向图中回路的几个节点无法进入栈,所以num如果小于节点数,说明有回路
    while(!s.empty())
    {
        idx=s.top();
        s.pop();
        Visited_Mark[idx]=1;//从栈中弹出一个节点,就把这个节点和他周围的弧删了,标记数组代表删除
        num++;
        for(p=VerNode_List[idx]->First_Edge; p!=nullptr; p=p->next)
        {
            k=p->Adjvex;
            cout<du--;
            if(VerNode_List[k]->du<2&&Visited_Mark[k]!=1)
                s.push(k);
        }
        cout<w= {0,1,2,3,4,5,6};
    Adjacency_List AL;
    AL.create(w,6);
    AL.output();
    cout<

 

你可能感兴趣的:(算法与数据结构)