您的位置:首页 > 其它

CodeForces 510B 无向图找环的两种方法(搜索与并查集)

2015-08-13 20:58 344 查看
题目连接:http://codeforces.com/problemset/problem/510/B

解法:

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: