CodeForces 510B 无向图找环的两种方法(搜索与并查集)
2015-08-13 20:58
344 查看
题目连接:http://codeforces.com/problemset/problem/510/B
解法:
dfs
每次把父节点的值记录并传递下去,判断一下新达到节点:
(1)没有走过 → 继续搜索;
(2)走过&&不是父节点(对于本题步数也要>=4) → 找到环;
并查集
每个节点映射成 i*m+j从起点开始分别把它下面与于右面的节点加进来,如果发现有节点已经在集合中,那么环已经找到了。
DFS:
并查集:
解法:
dfs
每次把父节点的值记录并传递下去,判断一下新达到节点:
(1)没有走过 → 继续搜索;
(2)走过&&不是父节点(对于本题步数也要>=4) → 找到环;
并查集
每个节点映射成 i*m+j从起点开始分别把它下面与于右面的节点加进来,如果发现有节点已经在集合中,那么环已经找到了。
DFS:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> ////////////////////// #include<iostream> #include<algorithm> #include<string> #include <iterator> #include<sstream> #include<functional> #include<numeric> /////////////////////// #include<vector> #include<map> #include <stack> #include<queue> #include<set> #include <bitset> #include <list> using namespace std; #define lch(x) ((x) << 1) #define rch(x) ((x)<<1|1) #define dad(x) ((x)>>1) #define lowbit(x) ((x)&(-x)) typedef long long int LL; const int INF = 0x4f4f4f4f ; const double eps = 1e-6; const long double PI = acos(0.0) * 2.0; const int N = 100+10; int n,m; char maze ; bool vis ; const int dx[] = {0,1,0,-1}; const int dy[] = {1,0,-1,0}; bool ok; bool dfs(int x ,int y,int px,int py,int cnt); int main() { //freopen("in.txt", "r", stdin); while(scanf("%d%d%*c",&n,&m) == 2) { memset(vis,0,sizeof(vis)); for(int i = 0 ; i < n ; i++) gets(maze[i]); ok = 0; for(int i = 0 ; i < n ; i++) for(int j = 0 ; j < m ; j++) if(!vis[i][j]) if(dfs(i,j,-1,-1,1)) { puts("Yes"); return 0; } puts("No"); } return 0; } bool dfs(int x ,int y,int px,int py,int cnt) { vis[x][y] = 1; for(int i = 0 ; i < 4 ; i++) { int nx = x +dx[i] , ny = y + dy[i]; if(0<= nx && nx < n && 0 <= ny && ny < m && maze[nx][ny] == maze[x][y]) { if(!vis[nx][ny]) dfs(nx,ny,x,y,cnt+1); else if( (nx != px || ny != py) && cnt>=4) ok = 1; } } return ok; }
并查集:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> ////////////////////// #include<iostream> #include<algorithm> #include<string> #include <iterator> #include<sstream> #include<functional> #include<numeric> /////////////////////// #include<vector> #include<map> #include <stack> #include<queue> #include<set> #include <bitset> #include <list> using namespace std; #define lch(x) ((x) << 1) #define rch(x) ((x)<<1|1) #define dad(x) ((x)>>1) #define lowbit(x) ((x)&(-x)) typedef long long int LL; const int INF = 0x4f4f4f4f ; const double eps = 1e-6; const long double PI = acos(0.0) * 2.0; const int N = 10000+10; int pre ; int _rank ; char maze ; int find(int x); int join(int x,int y); void ini(void); int same(int x,int y); int main() { ini(); int n,m; scanf("%d%d%*c",&n,&m); for(int i = 0 ; i < n ; i++) gets(maze[i]); for(int i = 0 ; i < n ; i++) { for(int j = 0 ; j < m ; j++) { if(maze[i][j] == maze[i+1][j] && i <n-1) { if(same(i*m+j,(i+1)*m+j)) {puts("Yes");return 0; } else join(i*m+j,(i+1)*m+j); } if(maze[i][j] == maze[i][j+1] && j < m-1) { if(same(i*m+j,i*m+j+1)) {puts("Yes");return 0; } else join(i*m+j,i*m+j+1); } } } puts("No"); return 0; } void ini(void) { int i; for(i = 0 ; i < N ; i++) pre[i] = i,_rank[i]=0; } int join(int x,int y) { int fx = find(x),fy = find(y); if(fx == fy) return 0; if(_rank[fx] > _rank[fy]) { pre[fy] = fx; } else { pre[fx] = fy; if(_rank[fx] == _rank[fy]) _rank[fy]++; } } //简化写法,使用递归 // int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]); } int find (int x) { int r = x; while(r != pre[r]) r = pre[r]; int i = x,j; while( r != pre[i]) { j = pre[i]; pre[i] = r; i = j; } return r; } int same(int x,int y) { return find(x) == find(y); }
相关文章推荐
- HDU 1429--胜利大逃亡(续)【BFS && 状态压缩】
- HDU1069_Monkey and Banana【LCS】
- Oracle ASM注意事项
- c# 调用c++ 使用指针传递的时候
- linux内核链表的使用
- HDU 4414 Finding crosses(dfs)
- 播放器 基本控件实现
- hdoj 1285 确定比赛名次 (经典拓扑排序题) 初学拓扑排序.做
- 计算几何中的精度问题
- poj 2485 Highways
- Lowest Common Ancestor of a Binary Tree(***)
- LeetCode-Implement Stack using Queues
- 【Oracle】minus的使用方法
- 有关lscroll的有关的问题~
- Hdu3501容斥原理
- Android开发问题:ActivityNotFoundException: Unable to find explicit activity class
- 乘法逆元
- hdu5375 Gray code(DP)
- 海量数据处理面试题
- HDU-5384