题意:要开启一扇门,n个单词是密码,n个单词中,如果一个单词的首字母和前一个单词的尾字母相同,并且每个单词都能这么连起来且只用一次,则门可以开启,否则不能开启,现给出单词,判断门是否可以开。

有向图欧拉通路充要条件:D为有向图,D的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为-1。

有向图欧拉回路充要条件:当D的所有顶点的出、入度都相等时,D中存在有向欧拉回路。

思路:一个单词关键是首字母和尾字母,可以把首字母和尾字母看成顶点,这个单词看成这两个顶点间的边,这么建图,于是原题就变成了找这个图中是否存在欧拉通路或者欧拉回路。建完图之后只需要根据定理判断每个顶点的出度、入度以及图的连通性即可。

转自:http://blog.csdn.net/zzzz40/article/details/38659755?utm_source=tuicool&utm_medium=referral

判断有多少个连通分量可以用并查集或者DFS。。我就都写了一遍

(其实是在给某人找错,就顺便写了一遍)

这是用并查集写的,写得不太好看。。(凑活看吧)

#include <cstdio>
#include <cstring>
using namespace std;
char a[1050],vis[26],VIS[26],f[26];
int cases,n,out[26],in[26],tot=0,temp,ans,ansx,ansy,len;
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
int main(){
scanf("%d",&cases);
while(cases--){
temp=ans=ansx=ansy=0;
for(int i=0;i<26;i++)f[i]=i;
memset(vis,0,sizeof(vis));
memset(VIS,0,sizeof(VIS));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",a);
len=strlen(a)-1;
a[0]-='a',a[len]-='a';
out[a[0]]++,in[a[len]]++;
if(!vis[a[len]])vis[a[len]]++;
f[find(a[len])]=find(a[0]);
}
for(int i=0;i<=25;i++)
if(vis[i]&&!VIS[find(i)])
VIS[find(i)]++,ans++;
if(ans>1){puts("The door cannot be opened.");continue;}
for(int i=0;i<=25;i++){
if(in[i]-out[i]==1)ansx++;
else if(out[i]-in[i]==1)ansy++;
else if(in[i]!=out[i])temp++;
}
if(ansx==ansy&&(ansx==1||ansx==0)&&!temp)puts("Ordering is possible.");
else puts("The door cannot be opened.");
}
}

DFS:

#include <cstdio>
#include <Cstring>
#include <algorithm>
using namespace std;
char a[1005];
bool vis[26],VIS[26],flag;
int cases,tot,v[200010],next[200010],first[2010],n,in[26],out[26];
int cnt1,cnt2,cnt3;
void add(int x,int y){v[tot]=y;next[tot]=first[x];first[x]=tot++;}
void dfs(int x){
for(int i=first[x];~i;i=next[i])
if(!VIS[v[i]])VIS[v[i]]=1,dfs(v[i]);
}
int main(){
scanf("%d",&cases);
while(cases--){
flag=1;tot=cnt1=cnt2=cnt3=0;
memset(first,-1,sizeof(first));
memset(vis,0,sizeof(vis));
memset(VIS,0,sizeof(VIS));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",a);
int len=strlen(a)-1;
a[0]-='a';a[len]-='a';
add(a[0],a[len]);
in[a[len]]++;out[a[0]]++;
vis[a[0]]=vis[a[len]]=1;
}
for(int i=0;i<26;i++){
if(in[i]!=out[i])cnt3++;
if(in[i]==out[i]-1)cnt1++;
if(out[i]==in[i]-1)cnt2++;
}
if(cnt3==2&&cnt1==1&&cnt2==1)
for(int i=0;i<26;i++){
if(in[i]<out[i]){
VIS[i]=1,dfs(i);
for(int i=0;i<26;i++)
if(vis[i]!=VIS[i])flag=0;
break;
}
}
else if(!cnt3){
dfs(a[0]);VIS[a[0]]=1;
for(int i=0;i<26;i++)
if(vis[i]!=VIS[i])flag=0;
}
else {puts("The door cannot be opened.");continue;}
if(flag)puts("Ordering is possible.");
else puts("The door cannot be opened.");
}
}

POJ 1386 判断欧拉回路的更多相关文章

  1. POJ 1386 Play on Words(欧拉图的判断)

    Play on Words Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11838   Accepted: 4048 De ...

  2. poj 1386 Play on Words 有向欧拉回路

    题目链接:http://poj.org/problem?id=1386 Some of the secret doors contain a very interesting word puzzle. ...

  3. poj 1386 Play on Words门上的单词【欧拉回路&&并查集】

    题目链接:http://poj.org/problem?id=1386 题目大意:给你若干个字符串,一个单词的尾部和一个单词的头部相同那么这两个单词就可以相连,判断给出的n个单词是否能够一个接着一个全 ...

  4. POJ 1386 Play on Words(单词建图+欧拉通(回)路路判断)

    题目链接:http://poj.org/problem?id=1386 题目大意:给你若干个字符串,一个单词的尾部和一个单词的头部相同那么这两个单词就可以相连,判断给出的n个单词是否能够一个接着一个全 ...

  5. poj 1386 Play on Words(有向图欧拉回路)

    /* 题意:单词拼接,前一个单词的末尾字母和后一个单词的开头字母相同 思路:将一个单词的开头和末尾单词分别做两个点并建一条有向边!然后判断是否存在欧拉回路或者欧拉路 再次强调有向图欧拉路或欧拉回路的判 ...

  6. HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)

    题目链接 题意 : 有很多门,每个门上有很多磁盘,每个盘上一个单词,必须重新排列磁盘使得每个单词的第一个字母与前一个单词的最后一个字母相同.给你一组单词问能不能排成上述形式. 思路 :把每个单词看成有 ...

  7. [欧拉回路] poj 1386 Play on Words

    题目链接: http://poj.org/problem?id=1386 Play on Words Time Limit: 1000MS   Memory Limit: 10000K Total S ...

  8. poj 1386 Play on Words(有向图欧拉路+并查集)

    题目链接:http://poj.org/problem?id=1386 思路分析:该问题要求判断单词是否能连接成一条直线,转换为图论问题:将单词的首字母和尾字母看做一个点,每个单词描述了一条从首字母指 ...

  9. POJ 1386 Play on Words(欧拉路)

    http://poj.org/problem?id=1386 题意: 给出多个单词,只有单词首字母与上一个单子的末尾字母相同时可以连接,判断所有字母是否可以全部连接在一起. 思路: 判断是否存在欧拉道 ...

随机推荐

  1. GrepWin:Win7下的文本替换工具

    工作环境退回到Win7之后,内容查找功能非常不给力,推荐一个文本内容查找工具grepWin. Win7下的文本查找/替换工具: grepWin

  2. C# 带Cookies发送请求

    #region --来自黄聪 void F1() { #region --创建cookies容器 添加Cookies和对应的URl(Hots主) CookieContainer cc = new Co ...

  3. 团体程序设计天梯赛-练习集-L1-042. 日期格式化

    L1-042. 日期格式化 世界上不同国家有不同的写日期的习惯.比如美国人习惯写成“月-日-年”,而中国人习惯写成“年-月-日”.下面请你写个程序,自动把读入的美国格式的日期改写成中国习惯的日期. 输 ...

  4. 整理Webview加载缓慢的解决方案

    1.https://www.cnblogs.com/xinye/p/3144139.html 2.https://www.jianshu.com/p/95d4d73be3d1

  5. MySQL NULL 值如何处理?

    我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作. 为了处理这种情况,MySQL提 ...

  6. Day 18 hashlib,logging模块

    hashlib 模块 作用:hash是一种算法,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法,该算法接受传入的内容,经过运算得到一串hash值 特点: 1.只要 ...

  7. 国密SSL证书申请免费试用

    沃通提供国密SSL证书免费申请试用服务,一次申请可同时签发SM2/RSA双算法证书,试用周期1个月,用于测试国密SM2 SSL证书的运行效果和SM2/RSA双证书部署效果. 试用产品:SM2/RSA双 ...

  8. webstorm中vue项目--运行配制

    ## npm搭建的项目,需要运行npm run dev来启动 webstorm作为一款优秀的编辑器,通过配置运行设置,达到一键运行 1.添加node.js配置 2.configuration-> ...

  9. 数组(day07)

    数组名称不可以代表存储区 数组名称可以代表数组里第一个存储区的地址 可以对数组名称进行sizeof计算,结果是 数组里所有存储区的总大小 C99规范里可以使用变长数组 声明变长数组的时候可以用变量表示 ...

  10. 洛谷P1060 开心的金明【dp】

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行&qu ...