深搜按条件剪枝:
1、与下一个点间不能有没经过的点
2、遇到预设折线直接沿路搜索
仅当num>=4和预设直线全部经过才增加sum
#include<iostream>
#include<map>
#include<string.h>
#include<algorithm>
#include<fstream>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
#define sqr(i) ((i)*(i))
#define pii pair<int,int>
#define mp make_pair
#define FOR(i,b,e) for(int i=b;i<=e;i++)
#define FORE(i,b,e) for(int i=b;i>=e;i--)
#define ms(a) memset(a,0,sizeof(a))
const int maxnum =21252;
const int mod = 10007;
int n,m;
struct node
{
int l1,l2;
}link[10];
bool check[10];
int uni(int i,int ln,bool se){
int p = i,next = ln;
while(1){
check[next]=se;
if(link[next].l1==p){
if(!link[next].l2)
return next;
p=next;
next=link[next].l2;
continue;
}
p=next;
next=link[next].l1;
}
}
int sum;
bool canchoose(int last,int now){
int lx=(last-1)%3,ly=(last-1)/3;
int nx=(now-1)%3,ny=(now-1)/3;
float midx = (float)(lx+nx)/2,midy=(float)(ly+ny)/2;
if(midx==int(midx)&&midy==int(midy)){//存在中间
if(!check[3*(int)midy+(int)midx+1])
return false;
}
return true;
}
bool dfs(int last,int now,int num){//check[now]==1
if(now){
if(!canchoose(last,now))return false;
int next;
if(link[now].l1!=last)
next=link[now].l1;
else
next=link[now].l2;
if(next){
check[now]=1;
if(!dfs(now,next,num+1)){
check[now]=0;
return false;
}
check[now]=0;
return true;
}
m--;
check[now]=1;
dfs(now,0,num+1);
check[now]=0;
return true;
}
if(m==0&&num>=4)
sum++;
if(num==9)return true;
FOR(i,1,9){//保证last和i没有预设连线
if((check[i]||!canchoose(last,i))&&last)continue;
if((link[i].l1&&link[i].l2))continue;
check[i]=1;
if(last==2){
last=2;
}
if(!link[i].l1){
dfs(i,0,num+1);
check[i]=0;
continue;
}
if(dfs(i,link[i].l1,num+1))
m++;
check[i]=0;
}
return true;//
}
int main()
{
#ifdef _DEBUG_
fstream fin("G:/1.txt");
#else
#define fin cin
#endif
int t,a,b;
fin>>t;
while(t--){
ms(check);
ms(link);
fin>>n;
FOR(i,1,n){
fin>>a>>b;
if(link[a].l1)
link[a].l2=b;
else
link[a].l1=b;
if(link[b].l1)
link[b].l2=a;
else
link[b].l1=a;
}
m=0;
FOR(i,1,9){
if(check[i])continue;
check[i]=1;
if(!link[i].l1&&!link[i].l2)
continue;
if(link[i].l1)
uni(i,link[i].l1,1);
if(link[i].l2)
uni(i,link[i].l2,1);
m++;
}
ms(check);
sum=0;
dfs(0,0,0);
cout<<sum<<endl;
}
return 0;
}