1. 程式人生 > 其它 >尤拉路徑的判斷(並查集,DFS)

尤拉路徑的判斷(並查集,DFS)

題目

我的題解

點選檢視程式碼
#include<bits/stdc++.h> 

using namespace std;

int main()
{
    map<int, int>mp;
    int n, m;
    cin >> n >> m;
 for (int i = 1;i < n+1;i++) {
        mp.insert(pair<int, int>(i, 0));
    }
 for (map<int, int>::iterator it = mp.begin();it != mp.end();it++) {
     //cout << it->first << " " << it->second << endl;
 }
    int a[10][2];
    for (int i = 0;i < m;i++) {
        for (int j = 0;j < 2;j++) {
            cin >> a[i][j];
            
        }
            int key1 = a[i][0];
            int key2 = a[i][1];
            map<int, int>::iterator it1 = mp.find(key1);
            it1->second++;
            map<int, int>::iterator it2 = mp.find(key2);
            it2->second--;
    }
    int count1 = 0;
    int count2 = 0;
    for (map<int, int>::iterator it = mp.begin();it != mp.find(n+1);it++) {
        //cout << it->first << " " << it->second<<endl;
        if (it->second <= -1)count1++;
        if (it->second >= 1)count2++;
    }
    //cout << count1 << count2 << endl;
    if ((count1 == 1) && (count2 == 1)) {
        cout << "Yes";
    }
    else {
        cout << "No";
    }

    return 0;
}

問題

沒有考慮沒有連通的情況

正確思路

1.先判斷是否連通,即連通分支數為1(可以用並查集或dfs)
2.只有一個結點入度為1,一個結點出度為1,其餘結點出度=入度

並查集

定義

把連通的兩個點合併,如果最後只有一個集合,那麼該圖連通,否則不連通。

實現

並查集由一個整數型的陣列和兩個函式構成。陣列pre[]記錄了每個點的前導點是什麼,函式find是查詢,join是合併。
陣列下標是當前點的號碼,值是前導點的號碼,如果值和下標一樣代表自己是根。
查詢是找根用的,直到找到值和下標一樣的根位置
合併就是在兩個根之間修改其中一個根的值為另一個根的下標或者值。
路徑壓縮演算法:最理想的情況就是所有點的前導點都是相同的根,一共就是兩級結構。做法就是在查詢時找到根之後把自身的值修改成根的下標。

正確程式碼