Sgu101

这道题是求一条能够连通所有骨牌的路径,一开始我吧骨牌当作节点,但这样明显是要超时的,后来经过讨论

其实可以吧骨牌上的数字当作节点,骨牌当作边,

这样做一遍Hierholzer's algorithm,找到一条记录顶点编号的欧拉路径,再从顶点搜索,直到吧边的序号搜索出来即可

/*
 *Name: Domino
 *LANG: C++
 *Source: sgu101
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
using namespace std;

struct node{
    int v,next;
}e[250];
int v[10],t[10],pre[250];
bool visit[250];
int path[250],pathNum;
int n,x,y,edgeNum;

void insert(int a,int b){
    e[++edgeNum].v=b;e[edgeNum].next=v[a];v[a]=edgeNum;t[a]++;t[b]++;
    e[++edgeNum].v=a;e[edgeNum].next=v[b];v[b]=edgeNum;t[a]++;t[b]++;
}
void dfs(int pos){
    if (t[pos]==0) {path[++pathNum]=pos;return;}
    int j=v[pos];
    while (j!=0){
	if (visit[(j+1)/2]){
	    visit[(j+1)/2]=false;
	    t[pos]--;t[e[j].v]--;
	    dfs(e[j].v);
	}
	j=e[j].next;
    }
    path[++pathNum]=pos;
}
int main(){
    //input
    scanf("%d",&n);
    for (int i=1;i<=n;++i){
	scanf("%d %d",&x,&y);
	insert(x,y);
    }
    //solve
    int tmp=0;int pos=-1,pos1=-1;
    for (int i=0;i<=6;++i) t[i]/=2;
    for (int i=6;i>=0;--i)
	if (t[i] % 2==1) {tmp++;if (t[i]!=0) if (pos==-1) pos=i; else pos1=-1;}
    if (pos==-1)
	for (int i=0;i<=6;++i)
	    if (t[i]!=0) {pos=i;break;}
    if (tmp!=2 && tmp!=0){
	printf("%s\n","No solution");
	return 0;
    }
    else{
	memset(visit,true,sizeof(visit));
	dfs(pos);
    }
    //print
    memset(visit,true,sizeof(visit));
    if (pathNum!=(n+1)) {printf("%s\n","No solution");return 0;}
    for (int i=1;i<pathNum;++i){
	int j=v[path[i]];
	while (j!=0 && (e[j].v!=path[i+1] || visit[(j+1)/2]==false))
	    j=e[j].next;
	visit[(j+1)/2]=false;
	if ((j+1) % 2==0)
	    printf("%d %c\n",(j+1)/2,'+');
	else
	    printf("%d %c\n",(j+1)/2,'-');
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值