1. 程式人生 > >圖割點求解問題

圖割點求解問題

來源自我的部落格

#include <stdio.h>
int flag[10];
int num[10];    // 記錄結點的訪問時間次序
int index;  // 時間
int low[10];    // 記錄結點不過父結點能訪問到的最早頂點

// 割點演算法核心
void dfs(int cur, int father){
    // 傳入引數為當前頂點編號和父頂點編號
    int child = 0;  // 記錄當前結點cur的兒子個數

    num[cur] = index;   // 當前結點的訪問時間
    low[cur] = index;   // 當前結點能訪問到的最早頂點,開始是自己
for (int i = 1; i <= n; i++){ // 列舉與當前結點cur有邊相連的頂點i if (e[cur][i] == 1){ // 根據記錄時間判斷當前結點有沒有被訪問過 if (num[i] == 0){ child++; dfs(i, cur); // 向下dfs low[cur] = min(low[cur], low[i]); // 更新能訪問的最早結點 // 判斷當前是不是割點
if (cur != root && low[i] >= num[cur]){ flag[cur] = 1; } // 根結點另判 if (cur == root && child = 2){ flag[cur] = 1; } } else if (i != father){ // 如果結點被訪問過,且不是當前結點的cur的父結點,則更新能訪問的最早結點
low[cur] = min(low[cur], num[i]); } } } } int main(){ int n, m; scanf("%d%d", &n, &m); int e[10][10]; // 邊 for (int i = 1; i <= n; i++){ for (int j = 1; j <= n; j++){ e[i][j] = 0; } } for (int i = 1; i <= m; i++){ int x, y; scanf("%d%d", &x, &y); e[x][y] = 1; e[y][x] = 1; } index = 1; // 初始時間為1 dfs(1, 1); // 從1號頂點開始進行深度優先遍歷 for (int i = 1; i <= n; i++){ if (flag[i] == 1){ printf("%d ", i); } } return 0; }