您的位置:首页 > 其它

例题6-16 UVA 10129 Play On Words单词

2016-02-23 00:09 459 查看
大体题意:

给你n个单词,问是否可以首尾相连,就是单词接龙!

思路:

看了下LRJ写的,用到了并查集判断有向图是否连通。

单词可以根据首字母,尾字母进行分类集合,最多26个集合!字母看作结点,单词看成有向边。

有解的情况:

1.必须连通

2.出度不等于入度的只能有0个或者2个!

有两个的情况还必须满足,一个出度比入度大1 (起点),入度比出度大1(终点)!

可以用lef表示剩余的连通图,当lef为1的时候表示可以连通!

然后把度数弄到deg数组里,入度++,出度--。

最后看是否为0.

#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 1000 + 10;
char str[maxn];
int is_use[26],pa[26],deg[26];
int findset(int x){return pa[x] == x ? x : pa[x] = findset(pa[x]);}
int main()
{
int T,N;
scanf("%d",&T);
while(T--){
for (int i = 0; i < 26; ++i)pa[i] = i;
memset(deg,0,sizeof(deg));
memset(is_use,0,sizeof(is_use));
scanf("%d",&N);
int lef = 26;
for (int i = 0; i < N; ++i){
scanf("%s",str);
char ch1 = str[0],ch2 = str[strlen(str)-1];
deg[ch1-'a']++;deg[ch2-'a']--;
is_use[ch1-'a'] = is_use[ch2-'a'] = 1;
int s1 = findset(ch1-'a'),s2 = findset(ch2-'a');
if (s1 != s2){--lef;pa[s1] = s2;}
}
vector<int >d;
for (int i = 0; i < 26; ++i){
if (!is_use[i])--lef;
else if (deg[i])d.push_back(deg[i]);
}
bool ok = false;
if (lef == 1 && d.empty())ok=true;
else if (d.size() == 2 && lef == 1 && ((d[0] == 1 && d[1] == -1) || (d[1] == 1 && d[0] == -1)))ok=true;
if (!ok)printf("The door cannot be opened.\n");
else printf("Ordering is possible.\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: