[题解]UVA10129 单词 Play on Words

UVA10129 单词 Play on Words

将各字母看做节点,单词的首字母向尾字母连一条有向边。最终如果该图存在欧拉通路,则答案合法。

回顾一下欧拉通路的判定:

  • 有向图是欧拉图\(\iff\)非零度节点弱连通,每个节点出入度相等
  • 有向图是半欧拉图\(\iff\)非零度节点弱连通,恰有一个节点出度\(-\)入度\(=1\),恰有一个节点入度\(-\)出度\(=1\),其他节点出入度相等。

上面两个条件满足其一即可。

我们将所有边看做无向边,用并查集维护连通性,即可实现弱连通的判定。

具体来说,每添加一条边\((u,v)\)就合并\(u,v\)所在集合,最终所有非零度(根据判定条件)节点都在一个集合中\(\iff\)该图联通。

用并查集的话,就不需要建图了。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,in[26],out[26],fa[26];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void init(){
memset(in,0,sizeof in),memset(out,0,sizeof out);
for(int i=0;i<26;i++) fa[i]=i;
}
bool solve(){
for(int i=0,p=-1;i<26;i++){
if(!in[i]&&!out[i]) continue;
if(find(i)!=p&&(~p)) return 0;
p=fa[i];
}
int cnts=0,cnte=0;
for(int i=0;i<26;i++){
if(in[i]==out[i]) continue;
if(out[i]-in[i]==1) cnts++;
else if(in[i]-out[i]==1) cnte++;
else return 0;
}
return (!cnts&&!cnte)||(cnts==1&&cnte==1);
}
signed main(){
cin>>t;
while(t--){
cin>>n;
init();
for(int i=1;i<=n;i++){
string s;cin>>s;
int l=s[0]-'a',r=s[s.size()-1]-'a';
in[r]++,out[l]++;
l=find(l),r=find(r);
if(l!=r) fa[l]=r;
}
cout<<(solve()?"Ordering is possible.\n":"The door cannot be opened.\n");
}
return 0;
}

附上无向图版本:P1333 瑞瑞的木棍题解

posted @   Sinktank  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
2025-2-27 8:11:33 TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2024 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.
点击右上角即可分享
微信分享提示