算法结果应该是 1-2-3 and 0-1-3-4, 而不是 0-1-2-3-4。
算法分解:
分配节点为1-n。
选择第一个节点,成为A
枚举A的所有输出节点对(pair)
选择一对节点,定义为A的邻接节点B、C
如果B和C连接,输出环ABC,返回第三步,选择其他节点对。
如果B和C不连接:
- 枚举B的所有连接点。假设连接点为D,E,F.生成一组向量:CABD, CABE, CABF,对于每一个向量:
- 如果最后一个点和其他点连接但不是B和C,丢弃该向量
- 如果最后一个点连接C,输出该向量,然后丢弃
- 如果最后一个点不和任何点相连,生成一组新向量,将所有点添加到最后一个点相连的向量。
重复,知道穷尽所有向量。
对于每对节点重复3-5步
删除节点1和它所有的连接选择下一个点回到第二步
初步代码,可能有bug,只作为展示想法:
void chordless_cycles(int* adjacency, int dim) { for(int i=0; i<dim-2; i++) { for(int j=i+1; j<dim-1; j++) { if(!adjacency[i+j*dim]) continue; list<vector<int> > candidates; for(int k=j+1; k<dim; k++) { if(!adjacency[i+k*dim]) continue; if(adjacency[j+k*dim]) { cout << i+1 << " " << j+1 << " " << k+1 << endl; continue; } vector<int> v; v.resize(3); v[0]=j; v[1]=i; v[2]=k; candidates.push_back(v); } while(!candidates.empty()) { vector<int> v = candidates.front(); candidates.pop_front(); int k = v.back(); for(int m=i+1; m<dim; m++) { if(find(v.begin(), v.end(), m) != v.end()) continue; if(!adjacency[m+k*dim]) continue; bool chord = false; int n; for(n=1; n<v.size()-1; n++) if(adjacency[m+v[n]*dim]) chord = true; if(chord) continue; if(adjacency[m+j*dim]) { for(n=0; n<v.size(); n++) cout<<v[n]+1<<" "; cout<<m+1<<endl; continue; } vector<int> w = v; w.push_back(m); candidates.push_back(w); } } } } }
http://stackoverflow.com/questions/4022662/find-all-chordless-cycles-in-an-undirected-graph