Hdu3812-Sea Sky(深搜+剪枝)
For example, from sea, he can associate with love, from love, he can see sky in (strange logic, aha? leave him alone, we don't really care how he imagine since he is so weird). In this way, he connects "Sea" and "Sky" in mind, fulfills his goal. However, he can only solve the puzzle with small number of words, when the connection increases, his brain will come to be a total mess. Now, can you smart guys help him?
Now iSea gives you some word pairs he can associate, from any one of them to another. He wishes use the maximum word to make an association list, from “sea” to “sky”, of course, no word should appear in the list twice because it would lead to an infinite loop. Your task is to find a list, which contains the maximum word and every neighbor word can be connected in mind. If several solutions exist, find the lexicographically minimum one. Lexicographical sequence is the order in one dictionary. For example, “cat” is less than “do”, and “do” is less than “dog”.
Input
Technical Specification
1. 1 <= T <= 50 2. 1 <= N <= 100 3. The number of different words and the length of words is no more than sixteen.
Output
Sample Input
Sample Output
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=;
int N,id,be,en;
string S1[maxn],S[maxn];
int d[maxn];
int root(int a){ return d[a]==a?a:d[a]=root(d[a]); }
bool G[maxn][maxn];
int GetId(string& s) //找到下标
{
for(int i=;i<=id;i++) if(S[i]==s) return i;
return ;
}
bool input()
{
N*=;
for(int i=;i<=N;i++)
{
cin>>S1[i];
S[i]=S1[i];
}
sort(S+,S+N+); //排个序
be=en=; //起点和终点编号
id=;
for(int i=;i<=N;i++)
{
if(S[i]!=S[id]) S[++id]=S[i]; //去重
if(S[id]=="sea") be=id;
if(S[id]=="sky") en=id;
}
if(!be||!en) return false; //没有sea或者sky
for(int i=;i<maxn;i++) d[i]=i; //并查集
memset(G,false,sizeof(G));
for(int i=;i<N;i+=)
{
int a=GetId(S1[i]); //下标
int b=GetId(S1[i+]);
int ra=root(a);
int rb=root(b);
G[a][b]=G[b][a]=true; //可连
if(ra!=rb) d[rb]=ra; //合并
}
if(root(be)!=root(en)) return false; //不在同一集合
return true;
}
bool vis[maxn],tvis[maxn];
int maxl,temp[maxn],ans[maxn];
bool dfs(int x,int step)
{
vis[x]=true;
temp[step]=x;
if(x==en) //到终点
{
if(step>maxl) //更新解
{
maxl=step;
for(int i=;i<=maxl;i++) ans[i]=temp[i];
}
if(step==id-) return true; //用完所有的
}
for(int i=;i<=id;i++)
if(!vis[i]&&G[x][i])
{
if(dfs(i,step+)) return true;
}
vis[x]=false;
return false;
}
bool Reach(int x,int y)
{
if(x==y) return true;
for(int i=;i<=id;i++)
if(!tvis[i]&&!vis[i]&&G[x][i])
{
tvis[i]=true;
if(Reach(i,y)) return true;
}
return false;
}
void solve()
{
memset(vis,false,sizeof(vis));
for(int i=;i<=id;i++)
{
memset(tvis,false,sizeof(tvis));
tvis[be]=true;
if(!Reach(i,en)) vis[i]=true; //能否到终点
}
for(int i=;i<=id;i++)
{
memset(tvis,false,sizeof(tvis));
tvis[en]=true;
if(!Reach(i,be)) vis[i]=true; //能否到起点
}
maxl=; //最大长度
dfs(be,); //深搜
}
int main()
{
int T,Case=;
cin>>T;
while(T--)
{
cin>>N;
if(!input()) //无解
{
printf("Case %d: what a pity\n",++Case);
continue;
}
solve();
printf("Case %d:",++Case);
for(int i=;i<=maxl;i++) cout<<" "<<S[ans[i]];
cout<<endl;
}
return ;
}
Hdu3812-Sea Sky(深搜+剪枝)的更多相关文章
- poj1190 生日蛋糕(深搜+剪枝)
题目链接:poj1190 生日蛋糕 解题思路: 深搜,枚举:每一层可能的高度和半径 确定搜索范围:底层蛋糕的最大可能半径和最大可能高度 搜索顺序:从底层往上搭蛋糕,在同一层尝试时,半径和高度都是从大到 ...
- UVA 10160 Servicing Stations(深搜 + 剪枝)
Problem D: Servicing stations A company offers personal computers for sale in N towns (3 <= N < ...
- ACM 海贼王之伟大航路(深搜剪枝)
"我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的 ...
- hdu 1518 Square(深搜+剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! ...
- POJ-1724 深搜剪枝
这道题目如果数据很小的话.我们通过这个dfs就可以完成深搜: void dfs(int s) { if (s==N) { minLen=min(minLen,totalLen); return ; } ...
- 一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>
题目传送 显然是道深搜题.由于蛋糕上表面在最底层的半径确认后就确认了,所以搜索时的面积着重看侧面积. 找维度/搜索面临状态/对象:当前体积v,当前外表面面积s,各层的半径r[],各层的高度h[]. 可 ...
- 模拟赛T5 : domino ——深搜+剪枝+位运算优化
这道题涉及的知识点有点多... 所以还是比较有意思的. domino 描述 迈克生日那天收到一张 N*N 的表格(1 ≤ N ≤ 2000),每个格子里有一个非 负整数(整数范围 0~1000),迈克 ...
- POJ2044 深搜+剪枝(云彩下雨)
题意: 有一个城镇,是4*4的大小的,然后你控制一块云彩,2*2的,你每天可以有9种走的方法,上下左右,或者不动,走的时候可以走1或者2步,云彩所在的地方肯定会下雨,然后给你做多365天 ...
- HDU 1175 连连看 (深搜+剪枝)
题目链接 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...
随机推荐
- poj3696:同余方程,欧拉定理
感觉很不错的数学题,可惜又是看了题解才做出来的 题目大意:给定一个数n,找到8888....(x个8)这样的数中,满足能整除n的最小的x,若永远无法整除n 则输出0 做了这个题和后面的poj3358给 ...
- c语言通过时间种子产生随机数并选出最大值以及下标
1 #include <stdio.h> #include <stdlib.h> #include <time.h> //2016 10 10 void main( ...
- 第35讲 Activity入门和跳转
第35讲Activity入门和跳转 1.Activity Activity是用户接口程序.在Android当中,Activity提供可视化的用户界面,一个Android应用通常由多个activity组 ...
- mysql语句添加索引
1.PRIMARY KEY(主键索引) mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2. ...
- Open Session In View
Open Session In View模式的主要思想是:在用户的每一次请求过程始终保持一个Session对象打开着 实现步骤: 步骤一.创建一个Web项目,创建包cn.happy.util,创建Hi ...
- Mysql User表为空
Mysql5.6刚安装完成,未设置过密码,root账号登录提示:root@localhost mysql]# mysqlERROR 1045 (28000): Access denied for us ...
- Linux目录和权限
1. rmdir -p 用来删除一串目录,是否可以成功删除? rmdir -p 删除一个不存在的目录时是否报错呢?rmdir -p 不能成功删除非空目录,rmdir -p 删除一个不存在的目录 ...
- C# 对象深复制
Mark: //实现IClonable接口并重写Clone方法就可以实现深克隆了 #region ICloneable 成员 public object Clone() { MemoryStream ...
- (转)简易WCF负载均衡方案
最近跟高老师讨论nginx跟tomcat集群做负载均衡方案.感觉很有意思.想到自己项目中服务用的WCF技术,于是就想WCF如何做负载均衡,Google了一会,发现wcf4.0的路由服务好像可以实现.不 ...
- Windows下使用ODBC API访问数据库之关键
本文采用SQL2005 + VS2008环境,以ODBC API方式成功连接数据库. 1.SQL安装和环境配置 这部分网上随便搜一下都有很多资料,而且很容易就可以配置成功. 注意的关键点: SA账号配 ...