1. 程式人生 > >無向圖判斷是否存在尤拉通路和歐拉回路

無向圖判斷是否存在尤拉通路和歐拉回路

利用並查集

#include<bits/stdc++.h>
#define PI 3.1415926

using namespace std;

const int maxn = 1003;
int P,Q;   ///P為頂點數,Q為邊數
int degree[maxn];  ///存放每個節點的度數
int father[maxn];  ///進行並查集操作的陣列
void make_set()
{
    for(int i = 1; i <= P; i++)
    {
        father[i] = i;
    }
}
int find_set(int x)
{
    return father[x]==-1?x:father[x]=find_set(father[x]);
}
void union_set(int x,int y)
{
    father[x] = y;
}
bool IsConnection() ///判圖是否連通
{
    int num = 0;
    for(int i = 1; i <= P; i++)
    {
        if(father[i]==-1)  ///自己所屬集合是自己點只能有一個
            num++;
    }
    if(num == 1) return true;
    else return false;
}
int main()
{
    int N,A,B;
    cin>>N;
    while(N--)
    {
        memset(father,-1,sizeof(father));
        cin>>P>>Q;
        memset(degree,0,sizeof(degree));
        //make_set();  ///初始化並查集
        for(int i = 0; i < Q; i++)
        {
            scanf("%d%d",&A,&B);
            degree[A]++;
            degree[B]++;
            int fa = find_set(A);
            int fb = find_set(B);
            if(fa!=fb)
                union_set(fa,fb);
        }
        int num = 0;
        for(int i = 1; i <= P; i++)
        {
            if(degree[i]%2)  ///統計奇度節點的個數
                num++;
        }
        ///如果奇度節點的個數是0個或2個,且圖是連通的則存在尤拉通路
        if((num==0||num==2)&&IsConnection())
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
//尤拉通路:圖連通;圖中只有2個度為奇數的節點(就是尤拉通路的2個端點)
//歐拉回路:圖連通;圖中所有節點度均為偶數
    return 0;
}