您的位置:首页 > 其它

poj1386 Play on Words

2012-08-26 09:53 471 查看
使用并查集判断连通性,然后再找欧拉通路。

#include <iostream>
using namespace std;

int n;
char st[1005];
bool exist[30];
int in[30], out[30];
int father[30];

int find_father(int a)
{
if (father[a] == a)
return a;
return father[a] = find_father(father[a]);
}

void merge(int a, int b)
{
father[find_father(a)] = find_father(b);
}

void input()
{
scanf("%d", &n);
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(exist, 0, sizeof(exist));
for (int i = 0; i < 26; i++)//初始化并查集
father[i] = i;
for (int i = 0 ; i < n; i++)
{
scanf("%s", st);
in[st[0] - 'a']++;
out[st[strlen(st) - 1] - 'a']++;
merge(st[0] - 'a', st[strlen(st) - 1] - 'a');//构建并查集
exist[st[0] - 'a'] = exist[st[strlen(st) - 1] - 'a'] = true;//把a、b两点记录为访问过的点
}
}

bool ok()
{
int start =0;
int end = 0;
int cnt = 0;
for (int i = 0; i < 26; i++)
if (father[i] == i && exist[i])//如果存在访问过的节点,并且祖先是自己,联通分量加1
cnt++;
if (cnt > 1)//如果不连通
return false;
for (int i = 0; i < 26; i++)
if (in[i] - out[i] == 1)
start++;
else if (out[i] - in[i] == 1)
end++;
else if (out[i] == in[i])
continue;
else
return false;
return start <= 1 && end <= 1;
}

int main()
{
int t;
scanf("%d", &t);
while (t--)
{
input();
if (ok())
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: