1. 程式人生 > >非遞迴的n頂點m顏色點著色問題

非遞迴的n頂點m顏色點著色問題

這應該是普及組都應該會的玩意吧。。。
做組合數學的數學題時,做到了一個求6頂點4顏色點著色種數的題,恕我直言,我不會用漂亮的方法來做,然而我這個不氪金的網遊一樣的腦袋就想著去寫個程式試試,結果發現我居然連深搜都無法寫出正確結果。再加上昨天CF史上新低,居然一題都沒過嚇壞了我們學校的學長。是時候反思一下了,省選臨近,雖然我是湊數的但是也不能掉以輕心啊。

剛剛是讀不讀都沒什麼影響的前言,下面正文。

如前面所說,我這樣反覆思之,細思極恐以後,趕緊去看了別人的部落格,後來看到了一個不遞迴的方法 趕緊學了。參考了這個qinyg大神寫的方法,雖然我不認識不過萬分感謝。

更讓我細思極恐的是,我居然第一次看無法完全理解這個方法,它不會重複計數嗎?事實再一次證明我的腦殘,我就是個zz吧,然後我就把數學卷子上的資料帶進去調才明白這是怎麼運作的,唉

我覺得現在的我思維有點凍結 我也不知道為什麼啊 qaq

過程是這樣的:最後一個else當且僅當k==n,color[k]>=m後的迴圈退回來以後,k為這個迴圈的k減一,由於是color[k]++所以會去嘗試不同的顏色;順序:從最後一個頂點嘗試完後退回倒數第二個,嘗試完到最後一個點後再回到倒數第二個,倒數第二個嘗試完後繼續回退。。。直至所有點嘗試完畢。

我相信大家的智商肯定比我這個弱智要高,給出程式碼qwq這是固定的6頂點4顏色方法(因為數學卷子上資料是這個)當然可以改為普通的n頂點m顏色方法,scanf一個n,m就完了

//這是固定的6頂點4顏色方法(因為數學卷子上資料是這個)
//當然可以改為普通的n頂點m顏色方法,scanf一個n,m就完了 #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn=100; int n=6; int m=4; int ans=0; vector<int > g[maxn]; int
color[maxn]; void addedge(int from,int to) { g[from].push_back(to); g[to].push_back(from); } bool check(int v) { for(unsigned i=0;i<g[v].size();i++) { int u=g[v][i]; if(color[u]!=0 && color[u]==color[v]) { return false; } } return true; } void colored() { int k=1; memset(color,0,sizeof(color)); while(k>=1) { color[k]++; while(color[k]<=m) { if(check(k)) { break; } else { color[k]++; } } if(k==n && color[k]<=m) { ans++; } else if(k<n && color[k]<=m) { k++; } else { color[k]=0; k--;//當且僅當k==n,color[k]>=m後的迴圈 //退回來以後,k為這個迴圈的k減一,由於是color[k]++ //所以會去嘗試不同的顏色 //順序:從最後一個頂點嘗試完後退回倒數第二個,嘗試完到最後一個點 //後再回到倒數第二個,倒數第二個嘗試完後繼續回退。。。直至所有點嘗試完畢。 } } } int main() { int from,to; while(scanf("%d%d",&from,&to)==2) { addedge(from,to); } colored(); printf("%d\n",ans); return 0; }

那麼繼續吧 我這個智障的oi歷程