可簡單圖化演算法(Havel演算法)
演算法分析(推理過程)
- 首先,我們很容易通過握手定理(所以點的度數加起來是偶數)知道,對應的度序列是否可圖化。
- 在確定了可圖化之後。但是擔心會出現不可簡單圖化的情況。
- 我們只需要對於這種可能進行討論就好了。
- 在可圖化,但是不可簡單圖化的這種圖中,就是因為會出現一些點上,一定會出現環(或者重邊)的情況
- 所以,我們只需要確定了一個固定的順序,這樣就可以解決掉這裡重邊的情況。(在作業系統中,關於解決死鎖的時候,也用了類似的一個解決方案來破掉死鎖的條件之一 —— 迴圈等待)。然後只允許前面的點與後面的點來構建邊,在這樣的邊建立完成之後,就不允許反過來的操作(這樣就避免重邊 情況)
- 所以,關鍵還是在環路的這種情況上
- 注意,這裡我們使用了前面已知的有序性。(這裡有序性就直接用度的有序性來做就好了(從大到小))
- 保證了上面的有序性還有一個作用,因為度大的點更有可能滿足條件。。(否則會出現負的情況)。
- 證明到這裡,其實已經可以確定了上面的演算法是可以確定一個充分條件,至於是不是必要條件,這個似乎還有待考究。
- 而仔細再推理一下,就會發現,其實這其實也是一個必要條件
- 因為,出現矛盾的情況,就是通過上面的排好序之後再選出來,結果判斷的是不可簡單圖化,但是我們可以找到一個簡單圖來描述
C++程式碼實現
核心程式碼:
int *a, N;
bool Havel() {
for (int i = N - 1; i >= 0; --i) {
sort(a, a + i+1); // sort the list
if (!a[i]) break;
for (int j = i - 1; j >= 0 && a[i]; j--) {
a[j]--; a[i] --;
if (a[j] < 0) return false;
}
if (a[i] > 0) return false; // 任然有剩餘
}
return true;
}
解釋:
- 在上面的演算法中,用系統自帶的排序。預設是從小到大來排序,所以,上面都是從後面來數的。
- 第一個判斷:
if (!a[i]) break;
表示,目前剩下的所有點的度都是0(在輸入的時候就保證了所有度都是大於等於0的) - 之後的for迴圈會最大的那些點都做處理,一直到a[i] == 0為止。
- 一旦出現了減完之後,後面的某些點變成了負數了,那麼說明就一定有問題了。否則就是可以繼續。
- 但是結束之後剩餘還有度數的話,就說明必有環了。
if (a[i] > 0) return false; // 任然有剩餘
#include <iostream>
using namespace std;
#include <algorithm>
int *a, N;
bool Havel() {
for (int i = N - 1; i >= 0; --i) {
sort(a, a + i+1); // sort the list
if (!a[i]) break;
for (int j = i - 1; j >= 0 && a[i]; j--) {
a[j]--; a[i] --;
if (a[j] < 0) return false;
}
if (a[i] > 0) return false; // 任然有剩餘
}
return true;
}
int main() {
cin >> N;
_ASSERT(N > 0);
a = new int[N];
int temp = 0;
bool gama = true;
for (int i = 0; i < N; ++i) {
cin >> a[i];
gama &= (a[i] >= 0);
temp += a[i];
}
if (!gama || temp % 2 || temp <= 0)
cout << false<< endl;
else
cout << Havel() << endl;
delete[] a;
system("pause");
}
相關推薦
序列可簡單圖化(Havel定理)
判斷數列是否可序列化。給定一個非負整數序列 (d1,d2,...dn) ,若存在一個無向簡單圖使得圖中各點的度與此序列一一對應,則稱此序列可簡單圖化。 輸入: 輸入有兩行 第一行輸入一個整數 N ,代表序列中非負整數的個數。 N <= 3000 第二行 N 個元素以空
可簡單圖化演算法(Havel演算法)
演算法分析(推理過程) 首先,我們很容易通過握手定理(所以點的度數加起來是偶數)知道,對應的度序列是否可圖化。 在確定了可圖化之後。但是擔心會出現不可簡單圖化的情況。 我們只需要對於這種可能進行討論
HDU 2454 Degree Sequence of Graph G (可簡單圖化的判定 havel定理)
題意:給出N個點的度(簡單圖),問能能否畫出個圖,(其實就是給出一個串非負的序列是否有對應的圖存在) 沒見過這個定理 題意真的難懂。 havel定理就是一個給出一串非負的序列,存在一個無向圖使得圖中各點的度與此序列一一對應,則稱此序列可圖化。簡單圖的話就是,可簡單圖化。
關於Havel演算法判斷度數序列能否構成簡單圖的思考
問題描述: Given a list of n natural numbers d1, d2,...,dn, show how to decide in polynomial time whether there exists an undirected graph G
Havel-Hakimi定理---通過度數列判斷是否可圖化
post 數列 討論 bsp 2個 HR lan degree ... 0、可圖:一個非負整數組成的序列如果是某個無向圖的度序列,則該序列是可圖的。 1、度序列:Sequence Degree,若把圖G所有頂點的度數排成一個序列,責成該序列為圖G的一個序列。該序列可以是非遞
谷歌百度以圖搜圖 "感知雜湊演算法" C#簡單實現
/// <summary> /// 感知雜湊演算法 /// </summary> public class ImageComparer { /// <summary> /// 獲取圖片的Hashcode /// &
從零開始Rtklib解讀篇-簡單的程式設計理論和演算法及結構分析(四)
首先我們來說一說VS常用的除錯技巧,比較常用的內容我會寫在下面。 1、斷點。我就不細說了。 2、條件斷點,在斷點上右鍵,彈出的選單可以選擇條件設定,在找一些問題的時候會比較快一點。我有時會配合靜態變數強行搜尋到error發生前。 3、檢視指標值,監視視窗輸入,比如p,3 ,即可檢視p
從零開始Rtklib解讀篇-簡單的程式設計理論和演算法及結構分析(三)
1. argc和argv argc和argv中的arg指的是"引數",首先是一個計算提供的引數到程式,第二個是對字串陣列的指標 argc: 整數,用來統計你執行程式時送給main函式的命令列引數的個數 * argv[ ]: 字串陣列,用來存放指向你
從零開始Rtklib解讀篇-簡單的程式設計理論和演算法及結構分析(二)
從bin裡進入。主進入方式為RTKLAUNCH.exe 第一個RTKPLOT右上角的小方塊可以勾選NormalAPs,RTKPOST_MKL,RTKPOST_WIN64, Minimize等選項。通常是第一個。另外64位系統下通常也是選用NormalAPs,RTKPOST_WIN
從零開始Rtklib解讀篇-簡單的程式設計理論和演算法及結構分析(一)
Rtklib一直開源,資源比較容易找到,功能也非常強大。因為專業有點相關,但是之前不用這個平臺,一直未能好好沉下心來學習,然而學到用時方恨少。這個系列也算是自己的一個小小的總結吧,因為我對VS、對Rtklib、對演算法的理解也比較淺,很多內容未必正確,寫的時候也不一定非常有條理,不當之處,還請指出並
雙向連結串列簡單實現--資料結構與演算法紀錄片第一記
從這個月開始得準備春招的東西,所以打算重新學習資料結構與演算法,以後的部落格就以這個為主。 今天是線性結構中的雙向連結串列。 程式碼實現與測試: DoubleLinkNode: package linear.doublelink;/** * @Description: 連結串列節點結
G - Oil Skimming ——二分圖匹配(匈牙利演算法)
G - Oil Skimming Thanks to a certain "green" resources company, there is a new profitable industry of oil skimming. There are large slicks of crude
ZOJ 3732 可圖性判定--Havel-Hakimi定理
題意:給定n個點度數,問是否可以構造一個簡單圖。 思路:Havel-Hakimi定理 : 1.將度數從小到大排序 2.用第一個向後面連續d[1]個點連邊,若點數不夠則不能構造 3.若點數夠,則將每個點度數減1,若出現負值,則不能構造, 4.去掉該點返回步驟一,直到集合中沒有點
導彈防禦塔---二分圖匹配《lyd演算法進階》
題目描述 Freda控制著N座可以發射導彈的防禦塔。每座塔都有足夠數量的導彈,但是每座塔每次只能發射一枚。在發射導彈時,導彈需要T1秒才能從防禦塔中射出,而在發射導彈後,發射這枚導彈的防禦塔需要T2分鐘來冷卻。 所有導彈都有相同的勻速飛行速度V,並且會沿著距離最短的路徑去打擊目標。計算防禦塔
51 nod 1212 無向圖最小生成樹(Kruckal演算法/Prime演算法圖解)
1212 無向圖最小生成樹 N個點M條邊的無向連通圖,每條邊有一個權值,求該圖的最小生成樹。 收起 輸入 第1行:2個數N,M中間用空格分隔,N為點的數量,M為邊的數量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 -
資料結構基礎之圖(中):圖的遍歷演算法
轉自:http://www.cnblogs.com/edisonchou/p/4676876.html 圖(中):圖的遍歷演算法 上一篇我們瞭解了圖的基本概念、術語以及儲存結構,還對鄰接表結構進行了模擬實現。本篇我們來了解一下圖的遍歷,和樹的遍歷類似,從圖的某一頂點出發訪問
雙目立體視覺匹配演算法之視差圖disparity計算——SAD演算法、SGBM演算法
一、SAD演算法 1.演算法原理 SAD(Sum of absolute differences)是一種影象匹配演算法。基本思想:差的絕對值之和。此演算法常用於影象塊匹配,將每個畫素對應數值之差的絕對值求和,據此評估兩個影象塊的相似度。該演
圖論初步-Tarjan演算法及其應用
暑假刷了一堆Tarjan題到頭來還是忘得差不多。 這篇部落格權當複習吧。 一些定義 無向圖 割頂與橋 (劃重點) 圖G是連通圖,刪除一個點表示刪除此點以及所有與其相連的邊。 若刪除某點u後G不再連通,那麼u是G的一個割頂(割點)。 若刪除某邊e後G不再連通,那麼e是G的一個橋。 雙連通 一個圖為雙
圖論動態規劃演算法——Floyd最短路徑
前言 推出一個新系列,《看圖輕鬆理解資料結構和演算法》,主要使用圖片來描述常見的資料結構和演算法,輕鬆閱讀並理解掌握。本系列包括各種堆、各種佇列、各種列表、各種樹、各種圖、各種排序等等幾十篇的樣子。 Floyd演算法 Floyd是一種經典的多源最短路徑演算法,它通過動態規劃的思想來尋找給定加權圖中的多源
簡單易學的機器學習演算法——Softmax Regression
Contents [hide] 1 簡介 2 代價函式 3 Softmax迴歸模型引數化的特點 4&nbs