标签:acm dfs 并查集 codeforces 图论
题目连接:http://codeforces.com/problemset/problem/510/B
解法:
并查集
每个节点映射成 i*m+j从起点开始分别把它下面与于右面的节点加进来,如果发现有节点已经在集合中,那么环已经找到了。
#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[N][N];
bool vis[N][N];
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[N];
int _rank[N];
char maze[N][N];
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);
}
版权声明:本文为博主原创文章,允许非商业性转载,转载必须注名作者(CSDN tt2767)与本博客链接:http://blog.csdn.net/tt2767。
CodeForces 510B 无向图找环的两种方法(搜索与并查集)
标签:acm dfs 并查集 codeforces 图论
原文地址:http://blog.csdn.net/tt2767/article/details/47610569