雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

判断是否存在哈密顿回路,DFS——zoj3526

Posted on 2011-08-29 14:22  huhuuu  阅读(2857)  评论(0编辑  收藏  举报
哈密顿回路判断是个NP问题,只有爆搜才可以
N=64,显然直接爆搜不行
AAAA……其实可以缩成一个点
ACACAC……缩成两个点(如单独存在A,C就需要两个AC)
ACGACGACG……缩成三个点(如单独存在A,C,G就需要三个ACG)
再DFS即可
View Code
#include<stdio.h>
#include
<string.h>

int add[10];
int ok=0;
int all=0;
int from;

void fun(char ss[10])
{
int i;
int t=0;
for(i=0;ss[i];i++)
{
if(ss[i]=='A')t+=4;
if(ss[i]=='C')t+=2;
if(ss[i]=='G')t+=1;
}
add[t]
++;
}

int fu(int f,int i)//判断相邻的点是否兼容
{
if(f==4)
{
if(i==6||i==5||i==7||i==4)return 1;
}
if(f==2)
{
if(i==6||i==3||i==7||i==2)return 1;
}
if(f==1)
{
if(i==5||i==3||i==7||i==1)return 1;
}
if(f==6)
{
if(i==1)return 0;
else return 1;
}
if(f==5)
{
if(i==2)return 0;
else return 1;
}
if(f==3)
{
if(i==4)return 0;
else return 1;
}
if(f==7)
{
return 1;
}
return 0;
}

void dfs(int f,int step)//爆搜是否存在这样一个环
{
int i;
if(ok==1)return;
if(step==(all-1)&&fu(f,from)==1)
{
ok
=1;
return;
}

for(i=1;i<=7;i++)
{
if(add[i]==0)continue;

if(fu(f,i)==0)continue;
add[i]
--;
dfs(i,step
+1);
add[i]
++;
}
}

void suo()//缩点
{
if(add[4]>=1)add[4]=1;
if(add[2]>=1)add[2]=1;
if(add[1]>=1)add[1]=1;
if(add[6]>=2)add[6]=2;
if(add[5]>=2)add[5]=2;
if(add[3]>=2)add[3]=2;
if(add[7]>=3)add[7]=3;
}

int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{

int i;
memset(add,
0,sizeof(add));
for(i=0;i<n;i++)
{
getchar();

char ss[10];
scanf(
"%*s %s",ss);

fun(ss);
}

suo();
all
=0;
for(i=1;i<=7;i++)
all
+=add[i];

ok
=0;
for(i=1;i<=7;i++)
{
if(ok==1)break;
if(add[i])
{
from
=i;
add[i]
--;
dfs(i,
0);
add[i]
++;
}
}
if(ok==1)printf("Yes\n");
else printf("No\n");
}
return 0;
}