搜索回溯。其实本来是比较简单的一个题,但因为看错题,刚开始做麻烦了,不过也AC了,觉得程序跑的有点慢,所以看了一下其他人写的代码,结果发现自己审错题想麻烦了。
题目中不会出现两个点之间出现多条重复边的情况,而我刚开始考虑到这种情况,由此便不能用二维数组 vis[x][y] 的方式表示某两点之间的边是否访问过,我是用了一个一维数组将所有边都存起来然再处理的,这样过程中会非常的麻烦。而如果不考虑两点之间的重复边,则直接用二维数组记录,则非常简单。
如(考虑两点之间重复边情况):
输入
2 4
1 0
0 1
1 0
0 1
输出
4
不考虑两点之间重复边则应输出 1.
代码如下:
考虑两点之间重复边情况:
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; int a[26][26], vis[27], tot, n, m; struct point { int x, y; } po[26]; void DFS(int x, int y, int cur, int fi) { int flag = 0; vis[fi] = 1; for(int i = 0; i < n; i++) if(a[y][i] == 1) { int fflag = 0; for(int j = 0; j < m; j++) // 在所有边中查找符合要求的边 { if((y == po[j].x && i == po[j].y) || (i == po[j].x && y == po[j].y)) if(!vis[j]) { fflag = flag = 1; DFS(y, i, cur + 1, j); } if(fflag) // 找到了就跳出,找不到就继续找,直到遍历过所有的边 break; } } vis[fi] = 0; if(!flag) { if(cur + 1 > tot) tot = cur + 1; } } int main() { #ifdef test freopen("sample.txt", "r", stdin); #endif memset(vis, 0, sizeof(vis)); while(scanf("%d%d", &n, &m)) { if(!m && !n) break; tot = 0; memset(a, 0, sizeof(a)); for(int i = 0; i < m; i++) { scanf("%d%d", &po[i].x, &po[i].y); a[po[i].x][po[i].y] = 1; a[po[i].y][po[i].x] = 1; } for(int i = 0; i < m; i++) { DFS(po[i].x, po[i].y, 0, i); DFS(po[i].y, po[i].x, 0, i); // 两个方向都可以走 } printf("%d\n", tot); } return 0; }
不考虑两点之间重复边情况:
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; int a[26][26], vis[26][26], tot, n; struct point { int x, y; } po[26]; void DFS(int x, int y, int cur) { int flag = 0; vis[x][y] = vis[y][x] = 1; for(int i = 0; i < n; i++) if(a[y][i] == 1 && !vis[y][i]) { flag = 1; DFS(y, i, cur + 1); } vis[x][y] = vis[y][x] = 0; if(!flag) { if(cur + 1 > tot) tot = cur + 1; } } int main() { #ifdef test freopen("sample.txt", "r", stdin); #endif int m; memset(vis, 0, sizeof(vis)); while(scanf("%d%d", &n, &m)) { if(!m && !n) break; tot = 0; memset(a, 0, sizeof(a)); for(int i = 0; i < m; i++) { scanf("%d%d", &po[i].x, &po[i].y); a[po[i].x][po[i].y] = 1; a[po[i].y][po[i].x] = 1; } for(int i = 0; i < m; i++) { DFS(po[i].x, po[i].y, 0); DFS(po[i].y, po[i].x, 0); // 两个方向都可以走 } printf("%d\n", tot); } return 0; }