博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1386 判断欧拉回路
阅读量:6293 次
发布时间:2019-06-22

本文共 2860 字,大约阅读时间需要 9 分钟。

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

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

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

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

(其实是在给某人找错,就顺便写了一遍)
这是用并查集写的,写得不太好看。。(凑活看吧)

#include 
#include
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 
#include
#include
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]

这里写图片描述

转载于:https://www.cnblogs.com/SiriusRen/p/6532413.html

你可能感兴趣的文章
js面向对象编程
查看>>
Ruby中类 模块 单例方法 总结
查看>>
jQuery的validate插件
查看>>
5-4 8 管道符 作业控制 shell变量 环境变量配置
查看>>
Enumberable
查看>>
开发者论坛一周精粹(第五十四期) 求购备案服务号1枚!
查看>>
validate表单验证及自定义方法
查看>>
javascript 中出现missing ) after argument list的错误
查看>>
使用Swagger2构建强大的RESTful API文档(2)(二十三)
查看>>
Docker容器启动报WARNING: IPv4 forwarding is disabled. Networking will not work
查看>>
(转)第三方支付参与者
查看>>
程序员修炼之道读后感2
查看>>
DWR实现服务器向客户端推送消息
查看>>
js中forEach的用法
查看>>
Docker之功能汇总
查看>>
!!a标签和button按钮只允许点击一次,防止重复提交
查看>>
(轉貼) Eclipse + CDT + MinGW 安裝方法 (C/C++) (gcc) (g++) (OS) (Windows)
查看>>
还原数据库
查看>>
作业调度框架 Quartz.NET 2.0 beta 发布
查看>>
mysql性能的检查和调优方法
查看>>