题意:
给定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 }