找所有簡單迴路

2021-10-11 18:49:20 字數 3425 閱讀 4694

我暫時沒找到好的方法,只能暴力,也沒有找到oj可以a題,所以也不知道**對不對

下面的**,只針對簡單圖

基本思路就是找回路,判重,回溯

#include#includeusing namespace std;

const int n = 1005, m = 1005;

typedef struct arcnode arcnode;

typedef struct vertexnode;

typedef struct algraph;

typedef struct list;

list cycles[m];//所有迴路

int path_num; //找到迴路個數

bool visit[n]; //是否訪問過

int path[n]; //臨時路徑

void init(algraph& g)

}void destroy(algraph& g)

g.adlist[i].first = null;

}}void add_edge(algraph& g, int u, int v)

/** * 判斷是否已經存在這條路徑

* @param start path中開始下標

* @param end path中結束下標+1

* @return true是|false否

*/bool check_exists(int start, int end)

//找起點位置

int start_id = 0;

while (start_id < cycles[i].length && cycles[i].data[start_id] != path[start])

if (start_id == cycles[i].length)

int j;

//比較是否相同

for (j = 1; j < path_length; ++j)

}if (j == path_length)

}return false;

}/**

* 深度優先遍歷

* @param g 有向圖鄰接表

* @param u 當前節點

* @param k 路徑長度

*/void dfs(algraph& g, int u, int k)

if (start < k && !check_exists(start, k))

cycles[path_num++].length = path_length;}}

else

}visit[u] = false;

}/**

* 找到所有簡單迴路

* @param g 有向圖鄰接表

* @param n 頂點數

*/void find_all_cycles(algraph& g)

}for (int i = 0; i < path_num; ++i)

else }}

}int main()

find_all_cycles(g);

destroy(g);

}return 0;

}

要防止0->1 ->0這種

#include#includeusing namespace std;

const int n = 1005, m = 1005;

typedef struct arcnode arcnode;

typedef struct vertexnode;

typedef struct algraph;

void init(algraph& g)

}void destroy(algraph& g)

g.adlist[i].first = null;

}}void add_edge(algraph& g, int u, int v)

//vector

typedef struct array;

array cycles[m]; //所有的迴路

int cycle_num; //迴路數量

int path[n]; //當前路徑

bool visit[n]; //訪問

/** * 判斷是否找到過這個迴路

* @param start 開始下標

* @param end 結束下標+1

* @return true找到|false沒找到

*/bool find_cycle(int start, int end)

int start_id = 0;

//找開始下標

while (start_id < cycles[i].length && cycles[i].data[start_id] != path[start])

if (start_id == cycles[i].length)

int j = 1;

//正著對一遍0->1->2->3->0

while (j < length && cycles[i].data[(start_id + j) % length] == path[start + j])

if (j == length)

j = 1;

//反著對一遍0->3->2->1->0

while (j < length && cycles[i].data[(start_id - j + length) % length] == path[start + j])

if (j == length)

}return false;

}/**

* 深度優先遍歷

* @param g 無向圖鄰接表

* @param u 當前頂點

* @param k 路徑長度

*/void dfs(algraph& g, int u, int k)

int length = k - start_id;

//判斷是否找到過,q且不能是0->1->0這種

if (start_id < k && length>2 && !find_cycle(start_id, k))

cycles[cycle_num++].length = length;}}

else

}visit[u] = false;//回溯

}/**

* 找到所有簡單迴路

* @param g 無向圖鄰接表

*/void find_all_cycles(algraph& g)

}for (int i = 0; i < cycle_num; ++i)

else }}

}int main()

find_all_cycles(g);

destroy(g);

}return 0;

}

PAT 1150 求簡單迴路

主要搞懂兩個概念 這次超時了,得了評分是21分,通過集合判斷是否是環和通過集合判斷是否周遊了全部節點顯然太耗時了,這是改善的空間 n,m map int input split graph matrix 1 n fori inrange n for index inrange m i,j dist ...

找位置(簡單模擬)

對給定的乙個字串,找出有重複的字元,並給出其位置,如 abcaaab12ab12 輸出 a,1 a,4 a,5 a,10,b,2 b,11,1,8 1,12,2,9 2,13。輸入描述 輸入包括乙個由字母和數字組成的字串,其長度不超過100。輸出描述 可能有多組測試資料,對於每組資料,按照樣例輸出的...

清華集訓2014 簡單迴路 插頭DP

鏈結 直接做q qq次插頭dp得分為60 6060 考慮題目中只詢問了豎直的邊,所以考慮分別做一遍前字尾插頭dp,記錄下每一行的每種輪廓線對應的方案數,詢問時合併輪廓線。兩條輪廓線互補相當於把輪廓線上的邊連起來能形成乙個環,用並查集判就行了。include using namespace std t...