1. 程式人生 > >CDOJ 1960 構造哈密頓路徑

CDOJ 1960 構造哈密頓路徑

AI tdi AC 希望 iostream CA mes return turn

題意:

給定n個點的有向完全圖,希望通過其中n-1條邊將n個點串起來(2<=n<=1000)

歐拉路徑:經過所有邊且只經過一次

哈密頓路徑:經過所有點且只經過一次

思路:

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

 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 }

CDOJ 1960 構造哈密頓路徑