0
点赞
收藏
分享

微信扫一扫

2025 : 简单环路 ( 并查集 判断图中是否有环 )


题目链接:点击打开链接

这道题我用的是并查集: 将题中图生成了一个无向图,标号为 i*m+j ( i, j 分别为行号, 列号, 下标均从 0 开始)

图中的 n*m 个点 编号分别为 : 0,1,2,3,... n*m-1 ; 

如果 map[x1][y1] == map[x2][y2] , 且 (x1, y1) 和 (x2, y2) 相邻 , 那么 点x1*m+y1 和 点 x2*m+y2 之间存在一条无向边。

注 : 并查集可以判断图中是否有环。 

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

const int N = 200010;
char map[55][55];
int road[4][2] = {-1,0, 1,0, 0,-1, 0,1};
int f[N];

int Find(int x)
{
    return x==f[x]?x:f[x]=Find(f[x]);
}

typedef struct edge
{
    int s, e;
} Edge;
Edge a[N];
int vis[55][55];

int main()
{
    int n, m;
    cin >> n >> m;
    memset(vis, 0, sizeof(vis));

    for(int i=0; i<n; i++)
    {
        cin >> map[i];
    }
    int cnt = 0;

    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            int temx, temy;
            for(int k=0; k<4; k++)
            {
                temx = i+road[k][0];
                temy = j+road[k][1];
                if(vis[temx][temy] || temx < 0 || temx > n || temy < 0 || temy > m)
                    continue;

                if(map[temx][temy] == map[i][j])
                {
                    int s = i*m+j, e = temx*m+temy;

                    a[++cnt].s = s;
                    a[cnt].e = e;
                    /*	a[++cnt].e = s;
                    	a[cnt].s = e;*/

                }
            }
            vis[i][j] = 1;
        }
    }

    int sroot, eroot;
    bool flag = 0;
    for(int i=0; i<=N-10; i++)
        f[i] = i;

    /* for(int i=1; i<=cnt; i++) {
     	cout << a[i].s << "-->" << a[i].e << endl;
    }*/

    for(int i=1; i<=cnt; i++)
    {
        sroot = Find(a[i].s);
        eroot = Find(a[i].e);

        if(sroot == eroot)
        {
            flag = 1;
            break;
        }
        else
            f[sroot] = eroot;
    }
    if(flag) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

 

 

 

 

举报

相关推荐

0 条评论