UVA10129 POJ1386 HDU1116 ZOJ2016 Play on Words【欧拉回路+并查集】
问题链接:UVA10129 POJ1386 HDU1116 ZOJ2016 Play on Words。
问题简述:先输入测试用例数T,每个测试用例包括整数N和N个单词数,问这些单词首尾字母能否接成一条龙?
问题分析:这是一个单词接龙问题,一个单词的尾字母和另外一个单词的首字母相同则可以接成龙。其中,每个单词只包含小写字母。单词的首字母和尾字母可以作为图的一个结点,从单词的首字母到尾字母画一条有向边,单词接龙问题就变成一笔画问题,或称为欧拉路径问题。
欧拉路径问题有两个条件,一是图是联通的;二是所有结点出入度相同,或者只有两个结点出入度差为1。
程序说明:用并查集来判定图是否是联通的。
程序提交后,除了POJ1386出现TLE,其他3个在线评判都AC了。在高人指点之下,程序中增加了69行的代码“ios::sync_with_stdio(false);”,就都可以通过了。这是由于C++的输入输出比较慢的原因,通过这行代码,改善了I/O的速度。
这个语句也可以写为“std::ios::sync_with_stdio(false);”。担心C++输入输出慢,可以使用该语句改善速度。
AC的C++语言程序如下:
/* UVA10129 Play on Words */
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
const int N = 26;
// 并查集类
int v[N];
class UF {
private:
int length;
public:
UF(int n) {
length = n;
for(int i=0; i<=n; i++)
v[i] = i;
}
// 压缩
int Find(int x) {
if(x == v[x])
return x;
else
return v[x] = Find(v[x]);
}
bool Union(int x, int y) {
x = Find(x);
y = Find(y);
if(x == y) {
return false;
} else {
v[x] = y;
return true;
}
}
};
int degreeout[N];
int degreein[N];
// 出入度检查:return nopathflag
bool degreeincheck()
{
int startcount = 0, endcount = 0;
for(int i=0; i<N; i++)
if(degreeout[i] != degreein[i]) {
if((degreeout[i] - degreein[i]) == 1) {
if(++startcount > 1)
return true;
} else if((degreeout[i] - degreein[i]) == -1) {
if(++endcount > 1)
return true;
} else
return true;
}
return false;
}
int main()
{
int t, n, src, dest;
ios::sync_with_stdio(false);
cin >> t;
while(t--) {
UF uf(N+1);
memset(degreeout, 0, sizeof(degreeout));
memset(degreein, 0, sizeof(degreein));
// 输入测试用例的数据,构建并查集,统计各个结点的度
cin >> n;
string s;
while(n--) {
cin >> s;
src = s[0] - 'a';
dest = s[s.size() - 1] - 'a';
degreeout[src]++;
degreein[dest]++;
uf.Union(src, dest);
}
// 判断图的联通性
bool nopathflag = false;
int root = -1;
for(int i=0; i<N; i++) {
if(degreeout[i] || degreein[i]) {
if(root == -1)
root = uf.Find(i);
else if(uf.Find(i) != root) {
nopathflag = true;
break;
}
}
}
// 判定是否存在欧拉路径:出入度检查
if(!nopathflag)
nopathflag = degreeincheck();
// 输出结果
if(nopathflag)
cout << "The door cannot be opened." << endl;
else
cout << "Ordering is possible." << endl;
}
return 0;
}
浙公网安备 33010602011771号