汉密尔顿回路 (25 分)【思路讲解】
立志用最少的代碼做最高效的表達
著名的“漢密爾頓(Hamilton)回路問題”是要找一個能遍歷圖中所有頂點的簡單回路(即每個頂點只訪問 1 次)。本題就要求你判斷任一給定的回路是否漢密爾頓回路。
輸入格式:
首先第一行給出兩個正整數:無向圖中頂點數 N(2<N≤200)和邊數 M。隨后 M 行,每行給出一條邊的兩個端點,格式為“頂點1 頂點2”,其中頂點從 1 到N 編號。再下一行給出一個正整數 K,是待檢驗的回路的條數。隨后 K 行,每行給出一條待檢回路,格式為:n V1 V?2 ? V?n
其中 n 是回路中的頂點數,V?i是路徑上的頂點編號。
輸出格式:
對每條待檢回路,如果是漢密爾頓回路,就在一行中輸出"YES",否則輸出"NO"。
輸入樣例:
6 10
6 2
3 4
1 5
2 5
3 1
4 1
1 6
6 3
1 2
4 5
6
7 5 1 4 3 6 2 5
6 5 1 4 3 6 2
9 6 2 1 6 3 4 5 2 6
4 1 2 5 1
7 6 1 3 4 5 2 6
7 6 1 2 5 4 3 1
輸出樣例:
YES
NO
NO
NO
YES
NO
漢密爾頓模板題。
漢密爾頓回路:
若圖中從某點出發,經過所有點一次后又重新回到起點,則該回路為漢密爾頓回路。
拓展:歐拉回路:
若圖中從某點出發,經過所有邊一次后又重新回到起點,則該回路為漢密爾頓回路。
判斷是否為漢密爾頓回路的條件:
1、數列起點與終點相同
2、數列每相鄰兩個點間為通路
3、除起點外,其他所有點都出現過一次(0次或2次以上都不行)
#include<iostream> #include<cstring> #include<vector>using namespace std; //稠密則數組,稀疏則鏈表 int G[210][210], vis[210]; int n, k;int main() {cin >> n >> k;for(int i = 0; i < k; i++) {int x, y; cin >> x >> y;G[x][y] = G[y][x] = 1;}/*漢密爾頓回路的條件:1、起點與終點相同2、每相鄰兩個點間為通路3、除起點外,其他所有點都出現過一次 */int m; cin >> m;for(int i = 0; i < m; i++) {int num; cin >> num;bool flag = true; //判斷是否為回路 memset(vis, 0, sizeof(vis)); //初始化 vector<int>v;for(int j = 0; j < num; j++) {int x; cin >> x; v.push_back(x);}int sta = v[0], fin = v[v.size()-1];if(sta != fin) flag = false; //情況1,起點與終點不同 for(int i = 1; i < v.size(); i++) {if(G[v[i-1]][v[i]] != 1) flag = false; //情況2相鄰點不通vis[v[i]]++;}for(int i = 1; i <= n; i++) {//情況3:除起點外,有點出現了兩次或沒出現過 if(vis[i] == 0 || (vis[i]==2 && i != sta)) flag = false;}cout << (flag ? "YES\n" : "NO\n"); }return 0; }
耗時:
??????——弱小和無知不是生存的障礙,傲慢才是。
總結
以上是生活随笔為你收集整理的汉密尔顿回路 (25 分)【思路讲解】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 列出连通集 (25 分)【DFS与BFS
- 下一篇: 城市间紧急救援 (25 分)【dijks