CDOJ 1960 構造哈密頓路徑

題意:ios

給定n個點的有向徹底圖,但願經過其中n-1條邊將n個點串起來(2<=n<=1000)spa

歐拉路徑:通過全部邊且只通過一次code

哈密頓路徑:通過全部點且只通過一次blog

思路:ci

本題條件特殊,有向徹底圖。構造法求解,將點插在head以前,tail以後,或head和tail之間(實際插在head後或tail前)string

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;  7 
 8 const int N=1e3+10;  9 int n,cnt; 10 const int INF = 0x3f3f3f3f; 11 char s[N]; 12 int g[N][N]; 13 int nxt[N]; 14 void solve() 15 { 16     cin>>n; 17     for(int i=0;i<n;i++) 18  { 19         scanf("%s",s); 20         int len = strlen(s); 21         for(int j=0;j<len;j++) 22  { 23             if(s[j]=='+') 24                 g[i][j]=1; 25  } 26  } 27     memset(nxt,-1,sizeof(nxt)); 28     int head=0; 29     int tail=1; 30     if(g[1][0])swap(head,tail); 31     nxt[head]=tail; 32     for(int i=2;i<=n-1;i++) 33  { 34         if(g[i][head]) // head以前
35  { 36             nxt[i]=head; 37             head=i; 38  } 39         else if(g[tail][i]){ // tail以後
40             nxt[tail]=i; 41             tail=i; 42  } 43         else // head和tail之間插點
44  { 45             int now = head; 46             while(nxt[now]!=-1) { 47                 if (g[now][i] && g[i][nxt[now]]) { 48                     nxt[i] = nxt[now]; 49                     nxt[now] = i; 50                     break; 51  } 52                 now = nxt[now]; 53  } 54  } 55  } 56     vector<int> ans; 57     while(head!=-1&&ans.size()<n) 58  { 59  ans.push_back(head); 60         head = nxt[head]; 61  } 62     if(ans.size()!=n) 63  { 64         puts("NO"); 65  } 66     else
67  { 68         puts("YES"); 69         for(int i=0;i<ans.size();i++) 70  { 71             if(i)cout<<" "; 72             cout<<ans[i]; 73  } 74  } 75     puts(""); 76 } 77 
78 int main() 79 { 80  solve(); 81     return 0; 82 }
相關文章
相關標籤/搜索