參考:
https://blog.csdn.net/a60782885/article/details/72655041
https://blog.csdn.net/yafeichang/article/details/53888866

1. 無向圖、有向圖、有權圖、有向有權圖

2. 表示方式:鄰接矩陣、邊的數(shù)組、鄰接鏈表

3. 遍歷:dfs——對應stack,先進后出。

      bfs——對應queue,先進先出

public class Graph {
    private List<Integer>[] adj; // 鄰接表
    private int V;  // 頂點數(shù)目
    private int E;  // 邊的數(shù)目
}
public void main(){
  for(int i=0;i<g.verticles;i++){
    if(!mark[i]){ 
      dfs(g,i);
      count++;
    }
  }
}
void dfs(Graph g,int start){
  mark[start]=true;
  count++;
  for(Integer i:adj[start]){
    if(!mark[i]){
      dfs(g,i);
    }
  }
}

void bfs(Graph g,int start){
  mark[start]=true;
  count++;
  Queue<Integer> queue = new LinkedList<Integer>();
  queue.add(start);
  while(queue.size()>0){
    int temp = queue.pop();
    for(Integer i:adj[start]){
       if(!mark[i]){
          mark[i]=true;
          count++;
         queue.add(i);
       }
     }
  }
}

4. 是否是連通圖

  • 法1:從一個點開始遍歷,遍歷記錄點的數(shù)目,如果最后的數(shù)目等于點數(shù),則連通;小于則不連通
  • 法2:floyed算法
    時間復雜度:O(N3)
    算法實現(xiàn):把相連的兩點設為dis[i][j]=true,不相連的兩點設為dis[i][j]=flase,用Floyed算法的變形:

floyd算法本來用以求圖中任意兩點間的最短路徑,大體思路是:依次以每個點k作為i--->j的中間節(jié)點,求d(i,j) = min(d(i,j),d(i,k)+d(k,j))
如果用floyd算法判斷任意兩個點的連通性?
可以直接用上面的算法,但是可以將加法和min操作轉為位運算。
d(i,j) = d(i,j) | (d(i,k) & d(k,j))

for(int k=1;k<=n;k++)
  for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    dis[i][j]=dis[i][j]||(dis[i][k]&&dis[k][j]);

最后如果dis[i][j]=true的話,表示兩點連通。
有向圖和無向圖都適用。

5. 兩個點是否連通

  • 記錄屬于哪個連通塊【用一個數(shù)組記錄】。判斷兩個點的數(shù)組id是否相同
  • 或者:從指定一個點出發(fā),進行一次遍歷,能夠從這個點出發(fā)到達的點就與起點連通的。這樣就可以求出這個頂點和其他頂點的連通情況。所以只要把每個頂點作為出發(fā)點都進行一次遍歷,就能知道任意兩個頂點之間是否有路存在。

6. 圖是否有環(huán)。

記錄前一個節(jié)點。如果在dfs過程中,下一個點被遍歷過且不是它的前一個節(jié)點,則說明有環(huán)

if(!marked[w])  
    dfs(g, w, v);  
else if(w != u)  
    hasCycle = true;  

7. 最小環(huán)

https://blog.csdn.net/qq_34731703/article/details/54729244
https://blog.csdn.net/Olga_jing/article/details/49928443
https://blog.csdn.net/cax1165/article/details/51811902
floyed算法圖解:
https://blog.csdn.net/qq_34374664/article/details/52261672

8. 二分圖

https://blog.csdn.net/yafeichang/article/details/53888866
可以被二著色的圖
思路:dfs的同時,對訪問點的連接點標成不同于當前點的顏色,當訪問到之前訪問的點,且兩個連接的點顏色相同時,說明這不是二分圖。

private void dfs(Graph g, int v) {  
        marked[v] = true;  
        for(int w : g.adj(v)) {  
            if(!marked[w]) {  
                color[w] = !color[v];  
                dfs(g, w);  
            } else if(color[w] == color[v])  
                isTwoColorable = false;  
        }  
    }  

9.圖的m著色問題

  1. 圖的m著色判定
  2. 圖的m著色優(yōu)化:
    若圖G是可平面圖,則它的色數(shù)不超過4色(4色定理).
    4色定理的應用:在一個平面或球面上的任何地圖能夠只用4種顏色來著色可使得相鄰的國家在地圖上著有不同顏色。

思路1:貪心。
任選一頂點著色1,在圖中盡可能多的用顏色1著色;
當不能用顏色1著色時,轉用顏色2將未著色的頂點盡可能多的著色···
直到所有頂點都被著色停止。
https://blog.csdn.net/lime1991/article/details/47805881
(有點麻煩。每次都要判斷是否還有未著色點)
思路2:如果顏色庫中的所有顏色都不能為1個點著色時,就新增一種顏色,然后對下一個點依舊從第一個顏色開始驗證
https://www.cnblogs.com/compilers/p/5480640.html

    for(i = 0; i < N;++i){   //遍歷每一個節(jié)點 vi
        for(j = 1; j <= cl ;++j){ //對vi 節(jié)點嘗試使用顏色 j來著色(1<= j <= cl)
            if(!isCollsion(a,c,i,j)){   // 若vi 著顏色j ,且與已經著色的節(jié)點(v0 - v(i-1))不發(fā)生任何著色沖突的話,就將vi著色為j
                c[i] = j;
                break;
            }
            if(c[i] == -1){  //若顏色庫中所有顏色都不能為vi節(jié)點 著色的話,就增加一種顏色,cl++;并將 該顏色賦予節(jié)點i
                c[i] = ++cl;
            }
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,094評論 25 709
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,014評論 2 59
  • 圖的定義與術語 1、圖按照有無方向分為無向圖和有向圖。無向圖由頂點和邊構成,有向圖由頂點和弧構成。弧有弧尾和弧頭之...
    unravelW閱讀 505評論 0 0
  • 我的婆婆今年90歲了,她一共生養(yǎng)了七個兒女,我的愛人是家里最小的孩子,這個四世同堂的大家族共有20多口人。 婆婆跟...
    雙子朗讀啦閱讀 820評論 9 9
  • 這幾天都被高考百日誓師刷屏,朋友說觀而有感,與我無關。是啊,已經與我無關,可是想起來還是會難過會想哭。對于那段時光...
    鴨蛋呀閱讀 194評論 0 0

友情鏈接更多精彩內容