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 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...
随机推荐
- 关于hibernate中对象的三种状态分析
一,首先hibernate中对象的状态有三种:瞬态.游离态和持久态,三种状态转化的方法都是通过session来调用,瞬态到持久态的方法有save().saveOrUpdate().get().load ...
- hdu 5392 Infoplane in Tina Town(数学)
Problem Description There is a big stone with smooth surface in Tina Town. When people go towards it ...
- Qt on Android:让 Qt Widgets 和 Qt Quick 应用全屏显示
Android 系统版本号非常多,较新的 4.4 ,较老的 2.3 ,都有人用. Qt on Android 开发的 Android 应用.默认在 Android 设备上是非全屏的. 而有些应用的需求 ...
- LeetCode 58 Spiral Matrix II
Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...
- c++11 线程:让你的多线程任务更轻松
介绍 本文旨在帮助有经验的Win32程序员来了解c++ 11线程库及同步对象 和 Win32线程及同步对象之间的区别和相似之处. 在Win32中,所有的同步对象句柄(HANDLE)是全局句柄.它们 ...
- git config配置文件 (共有三个配置文件)
设置 git status的颜色. git config --global color.status auto 一.Git已经在你的系统中了,你会做一些事情来客户化你的Git环境.你只需要做这些设置一 ...
- IP转发和子网路由
IP地址的分类 在TCP/IP协议中,协议栈分为4层.从上到下依次是应用层.运输层.网络层.网络接口层. IP协议就工作在网络层.IP协议将纷繁复杂的物理层协议屏蔽掉,对上层提供统一的描述和管理服务. ...
- DB2数据库全系列版本安装介质下载地址
网盘:http://pan.baidu.com/s/1qWE4D7A? ... qq-pf-to=pcqq.group官方:http://www-01.ibm.com/support/docview. ...
- C#调用VB6写的ActiveX Dll
搜索了很多资料,下载了Demo:http://download.csdn.net/detail/xieguoxian/2747484然后在同学电脑上测试才弄好...记录下 (一) 前期搜索资料: VB ...
- ListVeiw新增记录及 滚动条移动到指定位置
C# 自带的ListView控件的滚动条移动到指定位置. lvwList为ListView控件 lvwList.EnsureVisible(lvwList.Items.Count - 1); 新增记录 ...