您的位置:首页 > 其它

[构造] ICPC 2016 Hong Kong I. Special Tour

2017-03-30 08:23 435 查看
有一个n∗m的网格图,构造一条哈密尔顿回路使得相邻的两个点的距离为2或者3,如果无解输出无解。

n,m≤200

我是dls的脑残粉





#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

int n,m;
int flag;
inline void print(int x,int y){
if (flag) swap(x,y); printf("%d %d\n",x,y);
}

const int N=205;

struct edge{
int u,v,next;
}G[N*N*2];
int head[N*N],inum;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int vst[N*N];
#define V G[p].v
inline void dfs(int u){
vst[u]=1; print((u-1)/m+1,(u-1)%m+1);
for (int p=head[u];p;p=G[p].next)
if (!vst[V])
dfs(V);
}
#define DONE (dfs(1),exit(0))

#define P(x,y) (((x)-1)*m+(y))
inline void add(int x1,int y1,int x2,int y2){
add(P(x1,y1),P(x2,y2),++inum),add(P(x2,y2),P(x1,y1),++inum);
}

inline void Table();

int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d",&n,&m);
if ((n==3&&m==3)||(n==5&&m==5)||(n==3&&m==5)||(n==5&&m==3)) Table();
if (n>m) swap(n,m),flag^=1;
if (n==1){
if (m<10 && m!=5) return printf("-1\n"),0;
add(1,1,1,3),add(1,1,1,4),add(1,2,1,4),add(1,2,1,5);
if (m==5) add(1,3,1,5),DONE;
add(1,3,1,6);
for (int i=7;i<=m-4;i++) add(1,i,1,i-2);
add(1,m,1,m-2),add(1,m,1,m-3),add(1,m-1,1,m-3),add(1,m-1,1,m-4);
add(1,m-2,1,m-5);
DONE;
}else if (n==2){
if (m==2) return printf("-1\n"),0;
add(1,1,2,2),add(1,1,2,3),add(2,1,1,2),add(2,1,1,3);
for (int i=4;i<=m;i++) add(1,i,1,i-2),add(2,i,2,i-2);
add(1,m,2,m-1),add(2,m,1,m-1);
DONE;
}else if (n==4 || m==4){
if (n!=4) swap(n,m),flag^=1;
add(1,1,2,2),add(1,1,2,3),add(2,1,1,2),add(2,1,1,3);
for (int i=4;i<=m;i++) add(1,i,1,i-2),add(2,i,2,i-2);
add(3,1,4,2),add(3,1,4,3),add(4,1,3,2),add(4,1,3,3);
for (int i=4;i<=m;i++) add(3,i,3,i-2),add(4,i,4,i-2);
add(1,m-1,3,m),add(2,m,4,m-1),add(1,m,2,m-1),add(3,m-1,4,m);
DONE;
}else{
for (int k=1;k<=n;k++){
add(k,1,k,3),add(k,1,k,4),add(k,2,k,4),add(k,2,k,5);
add(k,3,k,6);
for (int i=7;i<=m;i++) add(k,i,k,i-2);
}
for (int i=1;i+2<=n;i+=2) add(i,m-1,i+2,m);
for (int i=2;i+2<=n;i+=2) add(i,m,i+2,m-1);
if (n&1)
add(1,m,2,m-1),add(n-1,m,n,m-1);
else
add(1,m,2,m-1),add(n-1,m-1,n,m);
DONE;
}
return 0;
}

inline void Table(){
if (n==3 && m==3) printf("1 1\n2 2\n3 3\n2 1\n1 2\n3 1\n2 3\n3 2\n1 3\n");
if (n==3 && m==5) printf("1 1\n2 2\n3 3\n2 4\n3 5\n1 4\n2 5\n3 4\n1 5\n2 3\n3 2\n1 3\n2 1\n1 2\n3 1\n");
if (n==5 && m==3) printf("1 1\n2 2\n3 3\n4 2\n5 3\n4 1\n5 2\n4 3\n5 1\n3 2\n2 3\n3 1\n1 2\n2 1\n1 3\n");
if (n==5 && m==5) printf("1 1\n2 2\n3 3\n4 4\n5 5\n4 3\n5 4\n4 5\n5 3\n4 2\n5 1\n3 2\n4 1\n5 2\n3 1\n2 3\n3 5\n1 4\n2 5\n3 4\n1 5\n2 4\n1 2\n2 1\n1 3\n");
exit(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐