HDU 1116 Play on Words 解题报告
解题思路:这道题的欧拉图是有向的,对于每个点都要统计入度和出度,判断时对于所有点,只有一个点入度比出度大1,只有一个点出度比入度大1,其他点入度出度必须相等。用并查集连接点。
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 200010;
const int maxn = 1e9;
using namespace std;
int n, len;
char a[1005];
int in[27];
int out[27];
int pre[27];
int visit[27];
int find(int x)
{
if (x != pre[x])
pre[x] = find(pre[x]);
return pre[x];
}
void union_set(int a, int b)
{
int pa = find(a);
int pb = find(b);
pre[pb] = pa;
return;
}
void solve()
{
scanf("%d", &n);
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(visit, 0, sizeof(visit));
for (int i = 0; i < 27; i++)
{
pre[i] = i;
}
for (int i = 0; i < n; i++)
{
scanf("%s", &a);
len = strlen(a);
int j = a[0] - 'a';
int k = a[len - 1] - 'a';
out[j]++;
in[k]++;
visit[j] = 1;
visit[k] = 1;
union_set(j, k);
memset(a, 0, sizeof(a));
}
int cnt = 0;
int a = 0, b = 0;
for (int i = 0; i < 27; i++)
{
if (visit[i])
{
if (in[i] - out[i] == 1)
{
a++;
}
if (out[i] - in[i] == 1)
{
b++;
}
if (out[i] - in[i] != 1&& out[i] - in[i] != -1&& out[i] - in[i] != 0)
{
printf("The door cannot be opened.\n");
return;
}
if (pre[i] == i)
{
cnt++;
}
if (cnt > 1)
{
printf("The door cannot be opened.\n");
return;
}
}
}
if (a == b && a <= 1)
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
return;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}