【Foreign】哈密顿回路 [MIM]

哈密顿回路

Time Limit: 15 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  

Sample Input

  4 10
  0 3 2 1
  3 0 1 3
  2 1 0 2
  1 3 2 0

Sample Output

  possible
  

HINT

  

Main idea

  判断能否找到一条长度为L的哈密顿回路。

Solution

  我们直接使用Meet in middle,记录M[t][opt]表示以 t 结尾,到的点为 opt 的长度集合。然后暴力合并即可。

Code

 1 #include<iostream>  
 2 #include<algorithm>  
 3 #include<cstdio>  
 4 #include<cstring>  
 5 #include<cstdlib>  
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 typedef long long s64;
10 
11 const int ONE = 230;
12 const int Base = 10007;
13 const int INF = 2147483640;
14 
15 int n;
16 int lenA,lenB;
17 s64 E[15][15];
18 int Num[ONE],vis[ONE],a[ONE];
19 s64 Ans,L;
20 
21 vector <s64> M[15][1<<15];
22 
23 int get()
24 {
25         int res=1,Q=1;    char c;
26         while( (c=getchar())<48 || c>57)
27         if(c=='-')Q=-1;
28         if(Q) res=c-48; 
29         while((c=getchar())>=48 && c<=57) 
30         res=res*10+c-48; 
31         return res*Q; 
32 }
33 
34 void Dfs(int u,int opt,int T,s64 Val)
35 {
36         if( Val > L) return;
37         if( T==lenA || T==lenB ) M[u][opt].push_back(Val);
38         if( T==max(lenA,lenB) ) return;
39         for(int v=1; v<=n; v++)
40         {
41             int now = opt | (1<<v-1);
42             if(now != opt) Dfs(v,now,T+1,Val+E[u][v]);
43         }
44 }
45 
46 int main()
47 {
48         n=get();    cin>>L;
49         lenA = (n+2)/2;        lenB = (n+2)-lenA;
50         for(int i=1; i<=n; i++)
51         for(int j=1; j<=n; j++)
52         {
53             scanf("%lld",&E[i][j]);
54         }
55         
56         Dfs(1,1,1,0);
57         
58         int All = (1<<n)-1;
59         
60         for(int u=1;u<=All;u++)
61         for(int t=1;t<=n;t++)
62             sort(M[t][u].begin(),M[t][u].end());
63         
64         for(int u=1;u<=All;u++)
65         for(int t=1;t<=n;t++)
66         {
67             if(! (u&(1<<t-1)) ) continue;
68             int v = All^u |1 | (1<<t-1);
69             int A_size = M[t][u].size(), B_size = M[t][v].size()-1;
70             for(int i=0;i<A_size;i++)
71             {
72                 s64 A = M[t][u][i];
73                 
74                 while(B_size >= 0 && M[t][v][B_size] + A > L) B_size--;
75                 if(B_size < 0) break;
76                 if(M[t][v][B_size] + A == L)
77                 {
78                     printf("possible");
79                     exit(0);
80                 }
81             }
82         }
83         
84         printf("impossible");
85 }
View Code
原文地址:https://www.cnblogs.com/BearChild/p/6550883.html