并查集&欧拉路

来源:互联网 发布:echo php 编辑:程序博客网 时间:2024/06/15 20:50

我的个人博客:地址

HDU1878——欧拉回路(并查集)

http://acm.hdu.edu.cn/showproblem.php?pid=1878

题意:这道题讲的是判断是否是一个欧拉回路。


欧拉通路: 通过图中每条边且只通过一次,并且经过每一顶点的通路。
欧拉回路: 通过图中每条边且只通过一次,并且经过每一顶点的回路。


无向图是否具有欧拉通路或回路的判定:
欧拉通路:图连通;图中只有0个或2个度为奇数的节点
欧拉回路:图连通;图中所有节点度均为偶数


有向图是否具有欧拉通路或回路的判定:
欧拉通路:图连通;除2个端点外其余节点入度=出度;1个端点入度比出度大1;一个端点入度比出度小1 或 所有节点入度等于出度
欧拉回路:图连通;所有节点入度等于出度

这道题的算法思路:利用并查集先判断图连通性,然后利用in数组记录各点的度。(因为该题是无向图)

判断条件:当一个点的根节点与其他点的根节点不等,则不连通,则返回0;当该点的度数是奇数时则非欧拉图,返回0;其他情况返回1

#include<cstring>#include<iostream>#include<cstdio>#define For(i, n) for(int i = 0; i < n; i++)using namespace std;const int MAXN = 30;int fa[MAXN], vis[MAXN], in[MAXN], out[MAXN];void Init()  // 初始化{    For(i, 26) { fa[i] = i, vis[i] = in[i] = out[i] = 0; }}int Find(int x)  //找老大{    int r = x;    while(fa[r] != r) {        r = fa[r];    }    return r;}void Union(int x, int y)  //合并{    int fx = Find(x);    int fy = Find(y);    if(fx != fy)        fa[fx] = fy;}int main(){    int t, n, x, y;    char str[1000 + 10];    bool flag;    cin >> t;    while(t--) {        Init();        cin >> n;        For(i, n) {            scanf("%s", str);            x = str[0] - 'a';            y = str[strlen(str) - 1] - 'a';            Union(x, y);            out[x]++;            in[y]++;            vis[x] = vis[y] = 1;        }        int r = 0;        For(i, 26) { if(vis[i] && fa[i] == i) r++; }        if(r > 1) flag = false;        else {                int n1 = 0;                int n2 = 0;                For(i, 26) {                    if(in[i] != out[i] && vis[i]) {                        if(in[i] - out[i] == 1)                            n1++;                        else if(out[i] - in[i] == 1)                            n2++;                       else n1 = 3; //判断第三种情况,两个单词相同(OK,OK)                    }                }                if( (n1 == 0 && n2 == 0) || (n1 == 1 && n2 == 1) )                    flag = true;                else flag = false;        }        if(flag) cout << "Ordering is possible." << endl;        else cout <<"The door cannot be opened." << endl;    }    return 0;}


借鉴 https://www.cnblogs.com/Yvettey-me/p/4541649.html

原创粉丝点击