1. 程式人生 > >有向圖和無向圖和樹判斷是否有環和無環

有向圖和無向圖和樹判斷是否有環和無環

圖只有樹邊和反向邊,如果有反向邊那麼就有環,否則就是樹或森林。

有向圖的code如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn=1001;
int vis[maxn];
int map[maxn][maxn];
int flag;
int n,m;
void input()
{
    memset(vis,0,sizeof(vis));
    memset(map,0,sizeof(map));
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;++i)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        map[a][b]=1;
    }
}
int dfs(int v)
{ 
    vis[v]=-1;
    flag=0;
    for(int i=1;i<=n;++i)
    {
        if(map[v][i]&&!vis[i])
        {
            dfs(i);
            vis[i]=1;
        }
        if(map[v][i]&&vis[i]==-1)
        {
            flag=1;
            break;
        }
    }
   return flag;
}
void judge()
{
    if(!flag)
        printf("Not a circle\n");
    else
        printf("Yes\n");
    return ;
}
int main()
{
     input();
     dfs(1);
     judge();
     return 0;
}
在進行深搜的時候,把深搜的點新增一個特殊標記,如果從當前的點往下搜的時候,發現這個標記,則立馬判定有環

再一個加大神的code:

#include <stdio.h>
#include <list>
#include <stack>
using namespace std;
list<int> edge[10003];
int n, m, current, used[10003];
bool find;

void clear(int used[]) {
    for (int i = 1; i <= n; ++i)
        used[i] = 0;
}

void print(int used[]) {
    for (int i = 1; i <= n; ++i)
        printf("%d", used[i]);
    printf("\n");
}

void dfs(int x) {
    used[x] = 1;
    for(list<int>::iterator it = edge[x].begin(); it != edge[x].end(); ++it) {
        if(*it == current) find = 1;
        if(find) break;
        if(!used[*it])
            dfs(*it);
    }
    if(!find) used[x] = 2;
}

void beginDFS(int x) {
    find = 0;
    clear(used);
    dfs(current = x);
    printf("%d: ", x);
    print(used);
}

int main() {
    if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
    scanf("%d %d", &n, &m);
    int x, y;
    for (int i = 0; i < m; ++i) {
        scanf("%d %d", &x, &y);
        edge[x].push_back(y);
    }
    beginDFS(1); beginDFS(2); beginDFS(3); beginDFS(4); beginDFS(5);

    return 0;
}

這是一個有向圖是否有環,是判斷某個點在不在環內 並輸出環上的點 

0是無法達到的點

1是能達到而且在環中的點

2是能達到但是不在環中的點

無向圖的code:

#include <iostream>

using namespace std;

const int M=501;
bool  g[M][M];
bool  visit[M];
bool  flag;
int   v,e;

bool dfs(int i,int pre)
{
    visit[i]=true;
    for(int j=1;j<=v;j++)
        if(g[i][j])
        {
            if(!visit[j])
                return dfs(j,i);
            else if(j!=pre)  //如果訪問過,且不是其父節點,那麼就構成環
                return false;
        }
}

int main()
{
    int i,j;
    while(cin>>v>>e)
    {
        memset(g,0,sizeof(g));
        while(e--)
        {
            cin>>i>>j;
            g[i][j]=g[j][i]=true;
        }
        memset(visit,0,sizeof(visit));
        flag=dfs(1,0);
        if(flag)
            cout<<"no\n";
        else
            cout<<"yes\n";
    }
    return 0;
}
用並查集也闊以來判斷是否有環,轉載的一個大神的程式碼:
#include <iostream>

using namespace std;

int parent[100002];

int UFfind(int i)
{
    int j;
    for(j=i;parent[j]>0;j=parent[j]);
    while(j!=i)
    {
        parent[i]=j;
        i=parent[i];
    }
    return j;
}

void UFunion(int i,int j)
{
    int temp=parent[i]+parent[j];
    if(parent[i]<parent[j])
    {
        parent[j]=i;
        parent[i]=temp;
    }
    else
    {
        parent[i]=j;
        parent[j]=temp;
    }
}

int main()
{
    int p,q,c,i,j,a,b;
    while(scanf("%d%d",&p,&q)!=EOF,!(p==-1&&q==-1))
    {
        c=0;
        a=0;
        b=p;
        memset(parent,-1,sizeof(parent));
        while(!(p==0&&q==0))
        {
            if(parent[p]==-1 && parent[q]==-1) //如果是兩個獨立點合併,則根節點數加1
                a++;
            else
                if(parent[p]!=-1 && parent[q]!=-1) //如果p,q不是同一顆樹,合併後根節點數減1,
                                                   //如果是同一顆樹,那麼在後面的判斷中會把c改為1,不影響後面的結果
                    a--;                           //這樣做很巧妙
            i=UFfind(p);
            j=UFfind(q);
            if(i!=j)
                UFunion(i,j);
            else
                c=1;
            scanf("%d%d",&p,&q);
        }
        if(!c && a==1 || b==0)
            printf("Yes\n");
        else
            printf("No\n");
    }
}
如果圖的父節點不止一個則一定不連通

相關推薦

判斷是否

圖只有樹邊和反向邊,如果有反向邊那麼就有環,否則就是樹或森林。 有向圖的code如下: #include<stdio.h> #include<string.h> #include<stdlib.h> const int maxn=1001

當一個標籤裡面多個class屬性的時候,如何判斷是否哪個屬性

如圖,選中的那一行<button>標籤,裡面的class值,有兩個,一個是startTime還有一個是chooseButton,我需要判斷是否含有chooseButton這個class,再進行相應的操作,當只有一個一個class的時候,我們可以通過$(this).attr('cla

檢測

路徑 深度遍歷 不可 兩個 說明 使用 插入 深度優先 標記 1.無向圖 並查集:檢查每一條邊的兩個端點是否是相同的連通子圖,如果是相同的,說明存在環; 深度遍歷:使用鄰接矩陣,只需要用一個數組標記是否訪問過,如果訪問過且不是該節點的父節點,則有環; 廣度優先:可以; 2.

DFS的運用(二分判定、的割頂橋,雙連通分量,的強連通分量)

part str stack void div prev this 沒有 2-sat 一、dfs框架: 1 vector<int>G[maxn]; //存圖 2 int vis[maxn]; //節點訪問標記 3 void dfs(int u

C語言利用的鄰接矩陣的儲存方式實現的深度優先搜尋(DFS)

C語言利用圖的鄰接矩陣的儲存方式實現有向圖和無向圖的深度優先搜尋(DFS) Description 圖採用鄰接矩陣儲存,圖中頂點數為n(0<n<20),頂點資訊為整數,依次為0,1,..,n-1。 編寫函式,輸入圖的型別,0:無向圖,1:有向圖;輸入圖的頂點數、邊數、邊的偶對

C語言利用的鄰接矩陣的儲存方式實現的廣度優先搜尋(BFS)

#include <stdio.h> #include <stdlib.h> #define Max_Vetex_Num 100 #define MAXSIZE 20 #define STACK_SIZE 30 typedef struct { int vexs[M

C語言利用的鄰接表的儲存方式實現求的入度出度以及的度數

Description 圖採用鄰接表為儲存結構,圖中的頂點數為n(0<n<=20),n個頂點的資訊依次為 0,1,...,n-1。 編寫程式,輸入圖的型別(0:無向圖,1:有向圖)、圖中頂點數、邊數、邊的偶對,建立圖的鄰接表。如果是無向圖,計算並輸出每個頂點的度;如果是有向圖,計

文章目錄 在和有向圖相關的實際應用中,有向環特別的重要。 優先順序限制下的排程問題:給定一組需要完成的任務,以及一組關於任務完成先後次序的優先順序限制。在滿足限制條件的前提下應該如何安排並完成所有任務? 對於任意一個這樣的問題,我們都可以畫出一張有向圖,其中頂點

用鄰接連結串列儲存

上一篇文章我們說到用鄰接矩陣儲存有向圖和無向圖,這種方法的有點是很直觀的知道點與點之間的關係,查詢的複雜度是為O(1)。但是這種儲存方式同時存在著佔用較多儲存空間的問題, 鄰接矩陣儲存很好理解,但是,有時候太浪費空間了,特別是對於頂點數多,但是關聯關係少的圖。 舉個極端

鄰接矩陣的輸入輸出,深度深度優先搜尋,廣度優先搜尋

#include<iostream> #include<stdlib.h> #include<malloc.h> #include<queue> #define MAXLEN 100 using namespace std; t

判斷是否迴路

一、無向圖迴路的判斷     對於無向圖,判斷其是否有迴路有四種方法,如下所示:     1、利用深度優先搜尋DFS,在搜尋過程中判斷是否會出現後向邊(DFS中,連線頂點u到它的某一祖先頂點v的邊),即在DFS對頂點進行著色過程中,若出現所指向的頂點為黑色,則此頂點是一個已

建立(陣列表示法)深度優先訪問

有向圖和無向圖差別就是一句程式碼的差別 ,無向圖中程式碼註釋掉即可 有向圖和有向網的差別也就是權值的差別  有向網需要賦予權值  有向圖有連線自動賦值為1 深度優先採用遞迴方法(參考前面幾篇文章,裡面有具體的深度優先和廣度優先訪問和佇列基本操作) 廣度優先採用佇列 上程

Tarjan 算法求的割頂

light cst tar clas 無向圖 oot getchar() als name #include <iostream> #include <cstdio> #include <algorithm> using n

DFSBFS()Java實現

ges return deque es2017 system let integer image class package practice; import java.util.Iterator; import java.util.Stack; import edu

2018/2/11 每日一學 割頂

return set else 所有 scanf ear .net 存在 sin 割頂和橋:對於無向圖G,如果刪除某個節點u後,連通分量數目增加,則稱u為圖的割頂;如果刪除某條邊後,連通分量數目增加,則稱該邊為圖的橋。 對於連通圖刪除割頂或橋後都會使得圖不再連通。 我們利用

Java數據結構算法(十五)——無權

java 指示 是我 如果 層次 引用 .com 號碼 mov   前面我們介紹了樹這種數據結構,樹是由n(n>0)個有限節點通過連接它們的邊組成一個具有層次關系的集合,把它叫做“樹”是因為它看起來像一棵倒掛的樹,包括二叉樹、紅黑樹、2-3-4

的割頂橋,的雙連通分量入門詳解及模板 -----「轉載」

dbr break nts word 否則 mark push gravity 無向連通圖 https://blog.csdn.net/stillxjy/article/details/70176689 割頂和橋:對於無向圖G,如果刪除某個節點u後,連通分量數目

小橙書閱讀指南(十二)——、深度優先搜索路徑查找算法

val 短路徑 clas 圖論 bsp 檢查 inf targe 自然 在計算機應用中,我們把一系列相連接的節點組成的數據結構,叫做圖。今天我們將要介紹它的一種形式——無向圖,以及針對這種結構的深度優先搜索和路徑查找算法。 一、無向圖數據結構 接口: /** * 圖論接

->連通性->的連通分量生成樹

文字描述   對無向圖進行遍歷時,對於連通圖,僅需從圖中任一頂點出發,進行深度優先搜尋或廣度優先搜尋,便可訪問到圖中所有頂點。但對非連通圖,則需從多個頂點出發搜尋,每一次從一個新的起始點出發進行搜尋過程得到的頂點訪問序列恰為其各個連通分量中的頂點集。   對於非連通圖,每個連通分量中的頂點集,和遍歷時走過

判斷是否存在尤拉通路歐拉回路

利用並查集 #include<bits/stdc++.h> #define PI 3.1415926 using namespace std; const int maxn = 1003; int P,Q; ///P為頂點數,Q為邊數 int degree[maxn]; /