博主歡迎轉載,但請給出本文鏈接,我尊重你,你尊重我,謝謝~
http://www.cnblogs.com/chenxiwenruo/p/6789799.html
特別不喜歡那些隨便轉載別人的原創文章又不給出鏈接的
所以不准偷偷復制博主的博客噢~~
先來擴展一下知識
哈密頓圖:
哈密頓圖是一個無向圖,由指定的起點通往指定的重點,途中經過所有節點有且只經過一次。
在圖論中,通常指的是哈密頓回路,即經過圖中所有頂點有且只有一次,最終回到出發點。
哈密頓回路為NP完全問題,暫不存在多項式內的解法。
歐拉圖:
類似的有歐拉圖:圖中經過每天邊有且只有一次,若最終回到出發點,則是歐拉回路。
判斷是否存在歐拉回路,是有定理的,網上可以找找。
然而這道題給出了路徑,判斷是否是哈密頓回路,瞬間感覺題目檔次下降了好多有沒有!!!
滿足了以下條件即輸出YES,只要有不滿足的就輸出NO:
1.路徑節點個數等於n+1
2.相鄰點之間存在連通的邊
3.前n點各只出現過1次
4.第一個節點等於最后一個節點,構成回路
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <vector> #include <cstring> #include <queue> using namespace std; const int maxn=205; int edge[maxn][maxn]; int n,m; int main() { int u,v; memset(edge,0,sizeof(edge)); scanf("%d %d",&n,&m); for(int i=0;i<m;i++){ scanf("%d %d",&u,&v); edge[u][v]=edge[v][u]=1; } int k; scanf("%d",&k); int n1; int vis[maxn]; for(int i=0;i<k;i++){ memset(vis,0,sizeof(vis)); scanf("%d",&n1); bool flag=true; //必須是n+1的頂點個數 if(n1!=n+1) flag=false; if(n1>0){ scanf("%d",&u); vis[u]=1; } int first=u; for(int j=1;j<n1;j++){ scanf("%d",&v); if(flag){ //得存在邊 if(!edge[u][v]){ flag=false; //break;傻了,這里怎么會寫了個break,導致一個樣例過不了。雖然false,但還是要繼續讀取數據的 } //前n個點必須只出現過一次 if(vis[v] && j!=n1-1) flag=false; else vis[v]=1; } u=v; } //第一個點等於最后一個點 if(v!=first) flag=false; if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
