精华内容
下载资源
问答
  • 数据结构+判断图中是否有回路

    千次阅读 2019-11-19 22:33:01
    数据结构–判断一个图中是否有环 bool VCycle(v) { bool flag; visited(v)=-1;//标记起始点 p=adjacent(v);//即p与v相邻 WHILE (p !=NULL) DO { if( visited(vertex(p))==-1) //又回到了起点,所以,存在环 { ...

    数据结构–判断一个图中是否有环
    bool VCycle(v)
    {
    bool flag;

    visited(v)=-1;//标记起始点

    p=adjacent(v);//即p与v相邻

    WHILE (p !=NULL)
    DO 
    {
    
    	if( visited(vertex(p))==-1) //又回到了起点,所以,存在环
    
    	{
    		flag=ture;
    		return flag;
    	}
    
    	if(visited(vertex(p))==0 )//没被访问过
    
    	{
    		flag=VCycle(vertex(p));//判断该点是否有回路
    		if(flag==ture)
    			return flag;
    	}
    	p=link(p);
    }
    

    visited(v)=1;//被访问过
    flag=false;//该点不成环
    return flag;
    }
    bool Cycle(G)//判断整个图是否有回路

    {
    Let v be the first vertex in G;//此处用英文理解吧

    WHILE v is existed DO (

    	IF visited(v) = 1 
    	THEN CONTINUE
    

    ;
    VCycle(v. flag) ;

    	IF flag=TRUE 
    	THEN RETURN
    

    ;
    Reset the status of visited vertices

    	Let v be the next vertex;)
    

    }

    展开全文
  • 这几天学习并查集,这一题收获挺大,1,并查集如何判断图中回路2.如何判断图的联通 这是参考别人的代码写的 #include struct node { int p; int r; }c[100005]; int flag[100005];//用于判断图是否连通 int ...

    小希的迷宫

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 6815    Accepted Submission(s): 2036

    Problem Description
    上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从 5到达8。

     

     

    Input
    输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
    整个文件以两个-1结尾。
     

     

    Output
    对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"Yes",否则输出"No"。
     

     

    Sample Input
    6 8 5 3 5 2 6 4 5 6 0 0 8 1 7 3 6 2 8 9 7 5 7 4 7 8 7 6 0 0 3 8 6 8 6 4 5 3 5 6 5 2 0 0 -1 -1
     

     

    Sample Output
    Yes Yes No
    这几天学习并查集,这一题收获挺大,1,并查集如何判断图中的回路2.如何判断图的联通
    这是参考别人的代码写的
    展开全文
  • 判断无向图中是否有回路

    万次阅读 多人点赞 2014-12-15 17:05:10
     第一种是类似拓扑排序的思路:(参考图判断回路的解答)   如果存在回路,则必存在一个子图,是一个环。因此该子图所有顶点入度>=1。 算法:   在图中,先找出入度为0的顶点,删除与这个顶点...

    关于无向图判断是否存在回路的方法:   
      第一种是类似有向图拓扑排序的思路:(参考有向图判断回路的解答) 
      如果存在回路,则必存在一个子图,是一个环。因此该子图中所有顶点入度>=1。 算法: 
      在有向图中,先找出入度为0的顶点,删除与这个顶点相关联的边(出边),将与这些边相关的其它顶点的入度减1,循环直到没有入度为0的定点。如果此时还有未被删除顶点,则必存在环路,否则不存在环路。  
    无向图则可以转化为: 
    如果存在回路,则必存在一个子图,是一个环路。因此环路中所有顶点的度>=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) 
     
    第二种为借助广度优先的策略: 

      任选一个顶点进行广度优先搜索。由于广度优先的算法本质就是从一个顶点出发将图按距离该顶点的远近层层展开为树形结构,如果存在某个顶点被访问两次表明树形展开层次结构中存在回边,因此则必存在回路。 或者利用BFS,在遍历过程中,为每个节点标记一个深度deep,如果存在某个节点为v,除了其父节点u外,还存在与v相邻的节点w使得deep[v]<=deep[w]的,那么该图一定存在回路; 

    第三种方法:
    遍历一遍,判断图分为几部分(假定为P部分,即图有 P 个连通分量)
    对于每一个连通分量,如果无环则只能是树,即:边数=结点数-1
    只要有一个满足      边数   >   结点数-1
    原图就有环
    将P个连通分量的不等式相加,就得到:
    P1:E1=M1-1
    P2:E2=M2-1
    ...
    PN:EN>MN-1
        所有边数(E)   >   所有结点数(M) - 连通分量个数(P)
    即:  E + P > M  所以只要判断结果  E  + P > M 就表示原图有环,否则无环.

      一种比较直接的思路是:为了要判断是否存在环路,需要在每个新近被加入访问队列的顶点上记录下该顶点的上一步的父顶点是哪一个,除了父顶点外其它相关顶点可以加入广度优先算法的队列,并将所有入队顶点的访问次数加一。如果发现访问次数>1的情况,则存在回路。反之,如果算法结束没有访问次数>1的情况则不存在回路。

    实例代码如下:

    1. #include<iostream>  
    2. #include<malloc.h>  
    3. using namespace std;  
    4. #define maxNum 100 //定义邻接举证的最大定点数  
    5. int visited[maxNum];//通过visited数组来标记这个顶点是否被访问过,0表示未被访问,1表示被访问  
    6. int DFS_Count;//连通部件个数,用于测试无向图是否连通,DFS_Count=1表示只有一个连通部件,所以整个无向图是连通的  
    7. int pre[maxNum];  
    8. int post[maxNum];  
    9. int point;//pre和post的值  
    10.   
    11. //图的邻接矩阵表示结构  
    12. typedef struct  
    13. {  
    14.     char v[maxNum];//图的顶点信息  
    15.     int e[maxNum][maxNum];//图的顶点信息  
    16.     int vNum;//顶点个数  
    17.     int eNum;//边的个数  
    18. }graph;  
    19. void createGraph(graph *g);//创建图g  
    20. void DFS(graph *g);//深度优先遍历图g  
    21. void dfs(graph *g,int i);//从顶点i开始深度优先遍历与其相邻的点  
    22. void dfs(graph *g,int i)  
    23. {  
    24.     //cout<<"顶点"<<g->v[i]<<"已经被访问"<<endl;  
    25.     cout<<"顶点"<<i<<"已经被访问"<<endl;  
    26.     visited[i]=1;//标记顶点i被访问  
    27.     pre[i]=++point;  
    28.     for(int j=1;j<=g->vNum;j++)  
    29.     {  
    30.         if(g->e[i][j]!=0&&visited[j]==0)  
    31.             dfs(g,j);  
    32.     }  
    33.     post[i]=++point;  
    34. }  
    35.   
    36. void DFS(graph *g)  
    37. {  
    38.     int i;  
    39.     //初始化visited数组,表示一开始所有顶点都未被访问过  
    40.     for(i=1;i<=g->vNum;i++)  
    41.     {  
    42.         visited[i]=0;  
    43.         pre[i]=0;  
    44.         post[i]=0;  
    45.     }  
    46.     //初始化pre和post  
    47.     point=0;  
    48.     //初始化连通部件数为0  
    49.     DFS_Count=0;  
    50.     //深度优先搜索  
    51.     for(i=1;i<=g->vNum;i++)  
    52.     {  
    53.         if(visited[i]==0)//如果这个顶点为被访问过,则从i顶点出发进行深度优先遍历  
    54.         {  
    55.             DFS_Count++;//统计调用void dfs(graph *g,int i);的次数  
    56.             dfs(g,i);  
    57.         }  
    58.     }  
    59. }  
    60. void createGraph(graph *g)//创建图g  
    61. {  
    62.     cout<<"正在创建无向图..."<<endl;  
    63.     cout<<"请输入顶点个数vNum:";  
    64.     cin>>g->vNum;  
    65.     cout<<"请输入边的个数eNum:";  
    66.     cin>>g->eNum;  
    67.     int i,j;  
    68.     //输入顶点信息  
    69.     //cout<<"请输入顶点信息:"<<endl;  
    70.     //for(i=0;i<g->vNum;i++)  
    71.     //  cin>>g->v[i];  
    72.     //初始画图g  
    73.     for(i=1;i<=g->vNum;i++)  
    74.         for(j=1;j<=g->vNum;j++)  
    75.             g->e[i][j]=0;  
    76.     //输入边的情况  
    77.     cout<<"请输入边的头和尾"<<endl;  
    78.     for(int k=0;k<g->eNum;k++)  
    79.     {  
    80.         cin>>i>>j;  
    81.         g->e[i][j]=1;  
    82.         g->e[j][i]=1;//无向图对称  
    83.     }  
    84. }  
    85. int main()  
    86. {  
    87.     graph *g;  
    88.     g=(graph*)malloc(sizeof(graph));  
    89.     createGraph(g);//创建图g  
    90.     DFS(g);//深度优先遍历  
    91.     //连通部件数,用于判断是否连通图  
    92.     cout<<"连通部件数量:";  
    93.     cout<<DFS_Count<<endl;  
    94.     if(DFS_Count==1)  
    95.         cout<<"图g是连通图"<<endl;  
    96.     else if(DFS_Count>1)  
    97.         cout<<"图g不是连通图"<<endl;  
    98.     //各顶点的pre和post值  
    99.     for(int i=1;i<=g->vNum;i++)  
    100.         cout<<"顶点"<<i<<"的pre和post分别为:"<<pre[i]<<" "<<post[i]<<endl;  
    101.     //cout<<endl;  
    102.     //判断无向图中是否有环  
    103.     if(g->eNum+DFS_Count>g->vNum)  
    104.         cout<<"图g中存在环"<<endl;  
    105.     else  
    106.         cout<<"图g中不存在环"<<endl;  
    107.     int k;  
    108.     cin>>k;  
    109.     return 0;  
    110. }  
    111. /* 
    112. 输入: 
    113. 正在创建无向图... 
    114. 请输入顶点个数vNum:10 
    115. 请输入边的个数eNum:9 
    116. 请输入边的头和尾 
    117. 1 2 
    118. 1 4 
    119. 2 5 
    120. 2 6 
    121. 4 7 
    122. 5 9 
    123. 6 3 
    124. 7 8 
    125. 9 10 
    126. */  

    注意:有向图不能使用此方法。比如1->2,1-3,2->3,4->5,如果使用上述方法会判定为含有还,但并非如此

    第四种方法:

    利用深度优先搜索DFS,在搜索过程中判断是否会出现后向边(DFS中,连接顶点u到它的某一祖先顶点v的边),即在DFS对顶点进行着色过程中,若出现所指向的顶点为黑色,则此顶点是一个已经遍历过的顶点(祖先),出现了后向边,若完成DFS后,则图中有回路。

    c - 顶点颜色表 c[u]

      0 白色,未被访问过的节点标白色

      -1 灰色,已经被访问过一次的节点标灰色

     1 黑色,当该节点的所有后代都被访问过标黑色

    深度优先遍历该图,如果在遍历的过程中,发现某个节点有一条边指向已经访问过的节点,并且这个已访问过的节点不是当前节点的父节点(这里的父节点表示dfs遍历顺序中的父节点),则表示存在环。但是我们不能仅仅使用一个bool数组来标志节点是否访问过。如下图

    image

    从节点1开始遍历-接着遍历2-接着遍历3,然后发现3有一条边指向遍历过的1,则存在环。但是回到1节点时,它的另一条边指向已访问过的3,又把这个环重复计算了一次。

    我们按照算法导论22.3节深度优先搜索中,对每个节点分为三种状态,白、灰、黑。开始时所有节点都是白色,当开始访问某个节点时该节点变为灰色,当该节点的所有邻接点都访问完,该节点颜色变为黑色。那么我们的算法则为:如果遍历的过程中发现某个节点有一条边指向颜色为灰的节点,那么存在环。则在上面的例子中,回溯到1节点时,虽然有一条边指向已经访问过的3,但是3已经是黑色,所以环不会被重复计算。

    下面的代码中visit数组的值分为0 1 2三种状态分别代表白色、灰色、黑色,调用函数dfs可以输出图中存在的所有环,图用邻接矩阵表示,如果两个节点之间没有边则对应的值为INT_MAX

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    void dfsVisit(vector<vector<int> >&graph, int node, vector<int>&visit,
                   vector<int>&father)
    {
        int n = graph.size();
        visit[node] = 1;
        //cout<<node<<"-\n";
        for(int i = 0; i < n; i++)
            if(i != node && graph[node][i] != INT_MAX)
            {
                if(visit[i] == 1 && i != father[node])//找到一个环
                {
                    int tmp = node;
                    cout<<"cycle: ";
                    while(tmp != i)
                    {
                        cout<<tmp<<"->";
                        tmp = father[tmp];
                    }
                    cout<<tmp<<endl;
                }
                else if(visit[i] == 0)
                {
                    father[i] = node;
                    dfsVisit(graph, i, visit, father);
                }
            }
        visit[node] = 2;
    }
     
    void dfs(vector<vector<int> >&graph)
    {
        int n = graph.size();
        vector<int> visit(n, 0); //visit按照算法导论22.3节分为三种状态
        vector<int> father(n, -1);// father[i] 记录遍历过程中i的父节点
        for(int i = 0; i < n; i++)
            if(visit[i] == 0)
                dfsVisit(graph, i, visit, father);
    }

    算法时间复杂度也是O(E+V)



    后向边:
       如果第一次访问(u,v)时v为灰色,则(u,v)为反向边。在对图的深度优先搜索中没有发现
       反向边,则该图没有回路。

    第五种方法:    

    在图的邻接表表示中,首先统计每个顶点的度,然后重复寻找一个度为1的顶点,将度为1和0的顶点从图中删除,并将与该顶点相关联的顶点的度减1,然后继续反复寻找度为1的,在寻找过程中若出现若干顶点的度都为2,则这些顶点组成了一个回路;否则,图中不存在回路。

    第六种方法:

    用BFS或DFS遍历,最后判断对于每一个连通分量当中,如果边数m>=节点个数n,那么改图一定存在回路。因此在DFS或BFS中,我们可以统计每一个连通分量的顶点数目n和边数m,如果m>=n则return false;直到访问完所有的节点,return true。 


    展开全文
  • 设快、慢两个指针:fast和slow,在程序开始时,二者都指向单链表的...),两指针进行追赶,若在任何一次循环两指针指向同一结点,则说明此单链表中有回路;而若二者任何一个指针指向了NULL(即到达了链表末尾),...

    设快、慢两个指针:fast和slow,在程序开始时,二者都指向单链表的链表头,之后循环移动两指针,fast指针在一次循环中向前移动两步(fast=fast->next->next;),slow指针则只移动一步(slow=slow->next;),两指针进行追赶,若在任何一次循环中两指针指向同一结点,则说明此单链表中有回路;而若二者中任何一个指针指向了NULL(即到达了链表末尾),则说明此单链表中没有回路。

    /*     判断链表是否有环    */
    
    int hasLoop(Node *head)
    
    {
    
        Node *p1,*p2;
    
        if(head == NULL || head->next == NULL) //链表为空,或是单结点链表直接返回头结点
    
            return 0;
    
        p1 = p2 = head;
    
        while(p1->next != NULL && p1->next->next != NULL)
    
        {
    
            p1 = p1->next->next;
    
            p2 = p2->next;
    
            if(p1 == p2)
    
                return 1;
    
        }
    
        return 0;
    
    展开全文
  • 设快、慢两个指针:fast和slow,在程序开始时,二者都指向单链表的链表头,之后循环移动两指针,fast指针在一次循环向前移动两步(fast=fast->.../* 判断链表是否有环 */ bool isLinkedListCo
  • 5——判断有图中是否存在回路

    万次阅读 多人点赞 2019-06-22 09:32:13
    假设以邻接矩阵作为的结构,编写算法,判别在给定的图中是否存在一个简单的回路,若存在,则以顶点序列的方式输出该回路(找到一条即可)(注意:中不存在顶点到自身的弧) 这是清华大学的考研试题。...
  • 算法——判断有向图是否有回路

    千次阅读 2020-06-12 19:36:24
    思路: 一.借助AOV的拓扑排序算法来对整个进行排序 拓扑排序算法: ...如果恰好等于节点总数,说明此图中没有回路 否则说明图中有回路 关键代码: int AOV::Topusort_AOV() { stack<int
  • 判断一个图中是否存在回路,并进行输出(拓扑算法)
  • 判断无向和有向图是否有回路

    万次阅读 多人点赞 2014-03-06 00:22:47
     对于无向判断是否有回路有两种方法,如下所示:  1、利用深度优先搜索DFS,在搜索过程中判断是否会出现后向边(DFS,连接顶点u到它的某一祖先顶点v的边),即在DFS对顶点进行着色过程,若出现所指向的...
  • (1)通过广度遍历(BFS)访问的所有点,对于每个点,都检测和已访问过的点是否有边(除了和它连接的上层节点)。 (1.1)如果有边,说明有回路(有环)。如果对于每个点,都没有和已访问过的点有边,说明从该点...
  • 判断无向图是否有回路

    千次阅读 2013-05-01 22:34:31
    1.初步认识  ... 前提:对于无向G,图中有结...判断,若此时图中无结点则原无向G回路,若图中结点存在则图中所有结点度数大于等于2,即图中总度数N>=2m,则图中剩下的的边数n>=m(因为一条边提供2个
  • 判断无向图是否有回路有四种方法

    万次阅读 2014-03-06 10:51:22
     对于无向判断是否有回路有四种方法,如下所示:  1、利用深度优先搜索DFS,在搜索过程中判断是否会出现后向边(DFS,连接顶点u到它的某一祖先顶点v的边),即在DFS对顶点进行着色过程,若出现所指向的...
  • 并查集判断无向图中是否存在回路

    千次阅读 2018-11-29 21:39:18
    并查集判断图中是否存在回路: A连接B,AB的pre本来不相同,Union使它们pre相同;B连接C,BC的pre本来不相同,Union使它们的pre相同; C连接A,AC的pre本来就相同,说明成环。 #include<bits/stdc++.h> ...
  • 如何判断一个图中是否存在回路

    千次阅读 2013-09-07 11:25:52
    问题描述:给一个G=,问如何判断这个图中是否存在回路?请给出至少3中方法 分析: 方法1:利用减枝的方法,如果G为:  1)首先删除入读为0的点,并且将对应的和该点相连的点的入读-1。(可以用一...
  • if(count)//由此判断有向图是否有回路 cout该有向回路"; } void main() { ALGraph G; CreateDG(G); cout拓扑排序:"; TopologicalSort(G); cout; } 测试用例一:   ...
  • 判断给定图是否存在回路

    千次阅读 2018-06-14 18:17:10
    判断给定图是否存在回路。输入第一行为图中顶点的个数n; 第二行为途中弧度条数e; 第二行为顶点信息;接着e行为e条弧依附的两个顶点。输出该图是否存在回路,是输出yes;,不是输出no。样例输入4 4A B C D A B...
  • 判断有图中回路

    2013-12-24 13:31:55
    数据结构的作业…拓扑排序 判断有图中的环并打印
  • JAVA代码详解: 图中判断欧拉路径和欧拉回路 欧拉路径是图中访问每一条边一次的路径。 欧拉回路是在同一顶点上开始和结束的欧拉路径。 欧拉回路称为欧拉图。 上一篇博客讨论了无向的欧拉回路。接...
  • 判断一个图是否存在回路

    千次阅读 2020-12-13 10:10:45
    loop函数无论是强连通和非强连通均能判断是否存在回路。 在loop函数 1.visited数组用于记录被访问过的节点,和DFS算法的visited数组相同。 2.count数组只有一个元素即count[0],初始值为1,若能找到回路,...
  • //对每个顶点v都进行一次深搜,如果深搜过程又能走回顶点v,则不在进行搜索,将回路标志flag置为1 #include<stdio.h> int a[6][6]={0}; int flag=0;//回路标记 //a[1][2]=1;a[1][5]=1;a[2][3]=1;a[3][1]=1; ...
  • 只需要记录每个单词的首尾字母,把每个字母当做中的点,两个字母出现在一个单词首尾当做一条向边,这样就成了求图中是否存在欧拉回路,即能遍历中所有的边而且不重复。 中存在欧拉回路的条件是:底...
  • 判断给定图是否存在回路 swustoj

    千次阅读 2018-05-05 16:05:38
    判断给定图是否存在回路 1000(ms) 10000(kb) 1465 / 3415Tags: 图判断给定图是否存在回路。输入第一行为图中顶点的个数n; 第二行为途中弧度条数e; 第二行为顶点信息;接着e行为e条弧依附的两个顶点。...
  • 判断给定图是否存在回路。 输入 第一行为图中顶点的个数n; 第二行为途中弧度条数e; 第二行为顶点信息;接着e行为e条弧依附的两个顶点。 输出 该图是否存在回路,是输出yes;,不是输出no。 样例输入 4 4 A B C D...
  • #include #include using namespace std;...//num用来判断每个节点的度是否为偶数 for(int j=1;j;j++) { if(juzhen[i][j]==1) num++; } if(num%2!=0) {//不是偶数,就输出0返回 cout; return 0; } } cout; return 0; }
  • 算法Cycle(G,v,has)从顶点v出发判断图G中是否存在回路,has是布尔值,初始调用时置为false,执行后若为true表示有回路,否则表示G中没有回路。 对应的算法如下: void Cycle(AGraph *G,int v,bool
  • 1076: 判断给定图是否存在回路 题目描述 判断给定图是否存在回路。 输入 第一行为图中顶点的个数n; 第二行为途中弧度条数e; 第二行为顶点信息;接着e行为e条弧依附的两个顶点。 输出 该图是否存在回路,是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,598
精华内容 11,439
关键字:

如何判断图中是否有回路