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 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...
随机推荐
- qq2013 java版(完整工程源码 包含服务端 oracle数据库)毕业设计有用
/** * 初始化组件 */ private void initComponent() { //提示面板 errorTipPane = new ErrorTipPane(); // 主面板 mainP ...
- IIS 问题解决
一.网站发布后 报500错误 解决办法:重新向iis注册framwork: 二.试图加载格式不正确的程序.(Exception from HRESULT: 0x8007000B) 解决办法:对应应用程 ...
- python倒计时
#coding=utf-8 #!/usr/bin/env python import datetime,time i=3 while i==3: spring=datetime.datetime(20 ...
- FileUtil.java
package com.founder.util.file; import java.io.BufferedReader; import java.io.File; import java.io.Fi ...
- Android中自定义ActionBar的背景色等样式style
Android中想要去自定义ActionBar的背景色等样式. [折腾过程] 1.自己找代码,发现对应的配置的地方了: AndroidManifest.xml ? 1 2 <applicatio ...
- docker 1.12.3版本搭建私有仓库,上传镜像报错:server gave HTTP response to HTTPS client”
系统环境:centos7 docker版本: 1.12.3(注意版本,可能存在不同版本设置不同的情况) docker registry版本:2.4.1 问题: 成功安装docker registry, ...
- python-文件压缩和解压
import tarfile #压缩 tar = tarfile.open('your.tar','w') tar.add('ooo.xml',arcname='ooo.xml') tar.close ...
- Fragment 点击事件的穿透和重叠bug
从A fragment跳转到B fragment ,为了返回时不从新加载A fragment内容,通常使用add方法来将a添加到后退栈. 在B Fragment 中点击一个空白区域,如果A Fragm ...
- 使用CMD连接SQL Server
在CMD中操作数据库,界面不美观,而且排版不整齐,但在机器上没有安装SQLSERVER的时候,也是极其方便的. 在命令行中输入 OSQL ?可以获得所有帮助信息 osql -S 数据库服务 ...
- Android开发环境的搭建之(一)Java开发环境的安装
(1) 安装JDK(Java Developer Kit).下载JDK1.8并安装jdk-8u60-windows-i586.exe.下载官方链接http://www.oracle.com/tech ...