【Foreign】哈密顿回路 [MIM]
哈密顿回路
Time Limit: 15 Sec Memory Limit: 256 MBDescription
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 }