hdu4337 King Arthur's Knights

n个顶点的图中,每个顶点度数大于等于n/2,该图一定存在哈密顿回路。

1.从该图中寻找一条极长链,使两个端点不存在不在链中的与其相邻的点。

2.如果这条链不是回路,一定可以在其中找到两个相邻点分别与两个端点相邻,使用这两个点把链变成回路。

3.如果这条链是回路,一定可以找到某个点,其与不在链中的点相邻,将该点与下一个点断开,继续扩展极长链。

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
using namespace std;
bool bmt[151][151];
struct lst{
	int qx,nx;
}eg[151];
#define clr(a) memset(a,0,sizeof(a))
int n,m;bool bd[151];
void _fdp(int&hd,int&tl,int&ns){
	int i,j;bool fg;
	while(1){
		for(fg=0,i=1;i<=n&&!fg;++i){
			if(bmt[i][hd]&&!bd[i]){
				fg=1;bd[i]=1,eg[hd].qx=i,eg[i].nx=hd;
				hd=i,++ns;
			}
		}
		for(i=1;i<=n&&!fg;++i){
			if(bmt[tl][i]&&!bd[i]){
				fg=1;bd[i]=1,eg[tl].nx=i,eg[i].qx=tl;
				tl=i,++ns;
			}
		}
		if(!fg)break;
	}
};
void _cycle(int hd,int tl){
	int i,j,ti;
	for(i=eg[hd].nx;!(bmt[tl][i]&&bmt[hd][eg[i].nx]);i=eg[i].nx);
	j=eg[i].nx,ti=i;
	for(;i;i=eg[i].nx){
		swap(eg[i].nx,eg[i].qx);
	}
	eg[hd].nx=j,eg[j].qx=hd;
	eg[tl].nx=ti,eg[ti].qx=tl;
};
void _cut(int&hd,int&tl){
	int i,j;bool fg;
	for(fg=0,i=1;i<=n&&!fg;++i){
		if(!bd[i]){
			for(j=1;j<=n&&!fg;++j){
				if(bmt[i][j]&&bd[j]){
					fg=1;hd=eg[j].nx,tl=j;
					eg[hd].qx=eg[tl].nx=0;
				}
			}
		}
	}
};
void _cl(){
	int i,j,ns,hd,tl;
	clr(eg),clr(bd);
	for(hd=tl=1;!bmt[hd][tl];++tl);
	eg[hd].nx=tl,eg[tl].qx=hd,ns=2;
	bd[hd]=bd[tl]=1;
	while(1){
		_fdp(hd,tl,ns);
		if(!bmt[hd][tl])
			_cycle(hd,tl);
		else
			eg[hd].qx=tl,
			eg[tl].nx=hd;
		if(ns==n)
			break;
		_cut(hd,tl);
	}
	printf("%d",hd);
	for(i=eg[hd].nx;i!=hd;i=eg[i].nx)
		printf(" %d",i);
	putchar('\n');
};
bool cl(){
	int i,u,v;
	if(scanf("%d %d",&n,&m)==-1)
		return 0;
	clr(bmt);
	for(i=0;i
       
       
      
      
     
     
    
    
   
   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值